From b1b725b15ba0cca303bb9ee3e7087f9734ebbcb3 Mon Sep 17 00:00:00 2001 From: svalo Date: Tue, 21 Apr 2026 11:07:16 +0200 Subject: [PATCH 01/60] fix(grid)grid: makes offsets for s1 and s2 consistent with l and m Offsets for 's' were not consistent with 'l' and 'm' causing unexpected behaviour. Now they all work the same Fixes: #657 --- sass/_grid.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sass/_grid.scss b/sass/_grid.scss index 67517447a0..1591b0cf39 100644 --- a/sass/_grid.scss +++ b/sass/_grid.scss @@ -65,8 +65,8 @@ body { .s11 { grid-column: auto / span 11; } .s12 { grid-column: auto / span 12; } - .offset-s1 { grid-column-start: 3; } - .offset-s2 { grid-column-start: 2; } + .offset-s1 { grid-column-start: 2; } + .offset-s2 { grid-column-start: 3; } .offset-s3 { grid-column-start: 4; } .offset-s4 { grid-column-start: 5; } .offset-s5 { grid-column-start: 6; } From b1486bda40728cdf5d89f4050d6157c8d8af1c63 Mon Sep 17 00:00:00 2001 From: svalo Date: Tue, 21 Apr 2026 14:19:07 +0200 Subject: [PATCH 02/60] fix(.github): Corrects path to CONTRIBUTING.md file --- .github/ISSUE_TEMPLATE/bug.yml | 6 +++--- .github/ISSUE_TEMPLATE/improvement.yml | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 41fbd6a07d..0d370daed1 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -10,7 +10,7 @@ body: options: - label: I have searched for [duplicate or closed issues](https://github.com/materializecss/materialize/issues?utf8=%E2%9C%93&q=is%3Aissue). required: true - - label: I have read the [CONTRIBUTING document](https://github.com/materializecss/materialize/blob/master/CONTRIBUTING.md) and my issue is following the guidelines. + - label: I have read the [CONTRIBUTING document](https://github.com/materializecss/materialize/blob/main/docs/CONTRIBUTING.md) and my issue is following the guidelines. required: true - label: I have read the template completely before filling it in. required: true @@ -50,10 +50,10 @@ body: attributes: label: Steps to reproduce description: | - If relevant, give a set of steps to reproduce this bug. + If relevant, give a set of steps to reproduce this bug. We encourage you a live example that demonstrates the bug (you may want to use the [following jsfiddle template](https://jsfiddle.net/1es0zhaf/)) placeholder: | - 1. Open this link + 1. Open this link 2. Click there 3. This appears, but... validations: diff --git a/.github/ISSUE_TEMPLATE/improvement.yml b/.github/ISSUE_TEMPLATE/improvement.yml index 6f87ce4f9d..21f5b0a397 100644 --- a/.github/ISSUE_TEMPLATE/improvement.yml +++ b/.github/ISSUE_TEMPLATE/improvement.yml @@ -8,7 +8,7 @@ body: options: - label: I have searched for [duplicate or closed issues](https://github.com/materializecss/materialize/issues?utf8=%E2%9C%93&q=is%3Aissue). required: true - - label: I have read the [CONTRIBUTING document](https://github.com/materializecss/materialize/blob/master/CONTRIBUTING.md) and my issue is following the guidelines. + - label: I have read the [CONTRIBUTING document](https://github.com/materializecss/materialize/blob/main/docs/CONTRIBUTING.md) and my issue is following the guidelines. required: true - label: I have read the template completely before filling it in. required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 067f057beb..45fa972eac 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,7 @@ ## Screenshots (if appropriate) or codepen: - + ## Types of changes @@ -14,8 +14,8 @@ ## Checklist: -- [ ] I have read the **[CONTRIBUTING document](https://github.com/materializecss/materialize/blob/main/CONTRIBUTING.md)**. -- [ ] My commit messages follows the [conventional commit format](https://github.com/materializecss/materialize/blob/main/CONTRIBUTING.md#submitting-your-pull-request) +- [ ] I have read the **[CONTRIBUTING document](https://github.com/materializecss/materialize/blob/main/docs/CONTRIBUTING.md)**. +- [ ] My commit messages follows the [conventional commit format](https://github.com/materializecss/materialize/blob/main/docs/CONTRIBUTING.md#submitting-your-pull-request) - [ ] My change requires a change to the documentation, and updated it accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. From 009d4c1e2f839fa7481776c34688384ae95b6b86 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Mon, 6 Jul 2026 15:42:24 +0200 Subject: [PATCH 03/60] build: examples and generate html for examples --- components/atomic/component.mjs | 17 +- components/atomic/page.mjs | 50 ++ components/grid/grid.js | 33 + examples/compile.sh | 4 + examples/html/blog.html | 11 + examples/html/landingpage.html | 12 + examples/html/portfolio.html | 10 + examples/src/blog.js | 40 ++ examples/src/landingpage.js | 27 + examples/src/portfolio.js | 31 + index.html | 7 + package-lock.json | 1142 ++++++++++++++++--------------- 12 files changed, 823 insertions(+), 561 deletions(-) create mode 100644 components/atomic/page.mjs create mode 100644 components/grid/grid.js create mode 100755 examples/compile.sh create mode 100644 examples/html/blog.html create mode 100644 examples/html/landingpage.html create mode 100644 examples/html/portfolio.html create mode 100644 examples/src/blog.js create mode 100644 examples/src/landingpage.js create mode 100644 examples/src/portfolio.js diff --git a/components/atomic/component.mjs b/components/atomic/component.mjs index b79e33c316..dfb82d5ec9 100644 --- a/components/atomic/component.mjs +++ b/components/atomic/component.mjs @@ -10,15 +10,20 @@ class Component { #tagname; #children; - #classnames; + #classNames; constructor(options) { this.#tagname = 'div'; this.#children = []; - this.#classnames = []; + this.#classNames = []; if (typeof options === 'object' && options.children) { // Tree Nodes - options.children.forEach((c) => this.addChild(c)); + if (typeof options.children === 'string') { + this.#children = options.children; + return; + } + const kids = Array.isArray(options.children) ? options.children : [options.children]; + kids.forEach((c) => this.addChild(c)); return; } // Text or numeric @@ -43,14 +48,14 @@ class Component { } addClassname(name) { - this.#classnames.push(name); + this.#classNames.push(name); return this; } toHTML() { const classAttr = - this.#classnames.length === 0 ? '' : ' class="' + this.#classnames.join(' ') + '"'; - if (typeof this.#children === 'object') + this.#classNames.length === 0 ? '' : ' class="' + this.#classNames.join(' ') + '"'; + if (typeof this.#children === 'object' && Array.isArray(this.#children)) return `<${this.#tagname}${classAttr}>${this.#children.map((child) => child.toHTML()).join('')}`; // string or number return `<${this.#tagname}${classAttr}>${this.#children}`; diff --git a/components/atomic/page.mjs b/components/atomic/page.mjs new file mode 100644 index 0000000000..01a13a9f08 --- /dev/null +++ b/components/atomic/page.mjs @@ -0,0 +1,50 @@ +import { Component } from './component.mjs'; + +class Page extends Component { + #title; + #metaDescription; + #styleList = []; + + constructor(options) { + super(options); + this.setTagName('html'); + if (options.title) this.setTitle(options.title); + } + + addStyleUrl(url) { + this.#styleList.push(url); + return this; + } + addJavascriptUrl() { + return this; + } + setTitle(title) { + this.#title = title; + return this; + } + setMetaDescription(descr) { + this.#metaDescription = descr; + return this; + } + // override + toHTML() { + return ` + ${this.#title} + ${this.#styleList + .map( + (s) => `` + ) + .join('')} + + + +
+ ${super.toHTML()} +
+ `; + } +} + +class Container extends Component {} + +export { Page, Container }; diff --git a/components/grid/grid.js b/components/grid/grid.js new file mode 100644 index 0000000000..c028923814 --- /dev/null +++ b/components/grid/grid.js @@ -0,0 +1,33 @@ +import { Component } from '../atomic/component.mjs'; + +class Grid extends Component { + #numberOfRows; + #numberOfColumns; + #children; + + constructor(options) { + const x = options.children; + delete options.children; + super(options); + this.#children = x; + this.setTagName('button'); + this.addClassname('btn'); + } + + setColumns(number) { + this.#numberOfColumns = number; + return this; + } + // setRows(number) { + // this.#numberOfRows = number; + // return this; + // } + + toHTML() { + const childs = this.#children; + const rows = childs.map((c) => `
${c}
`); + return `
${rows.join('')}
`; + } +} + +export { Grid }; diff --git a/examples/compile.sh b/examples/compile.sh new file mode 100755 index 0000000000..2f1c6f9df7 --- /dev/null +++ b/examples/compile.sh @@ -0,0 +1,4 @@ +#!/bin/bash +node src/blog.js > html/blog.html +node src/landingpage.js > html/landingpage.html +node src/portfolio.js > html/portfolio.html diff --git a/examples/html/blog.html b/examples/html/blog.html new file mode 100644 index 0000000000..cb2bccb2ef --- /dev/null +++ b/examples/html/blog.html @@ -0,0 +1,11 @@ + + My Blog + + + + +
+

Blog

This is a featured Post
2 or 3-column masonry grid showing article thumbnails, titles, and publication dates
[object Object]This is a test Landingpage. ok it can produce nested html too...
+ Or you can go to the Portfolio
Sidebar or navigation dropdowns ("Tech," "Lifestyle")
+
+ diff --git a/examples/html/landingpage.html b/examples/html/landingpage.html new file mode 100644 index 0000000000..513f0356d2 --- /dev/null +++ b/examples/html/landingpage.html @@ -0,0 +1,12 @@ + + My Landingpage + + + + +
+

Landing Page

Hero Section
A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
+ feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.
+ You can also checkout the Blog
Hello, this is my landing page!
+
+ diff --git a/examples/html/portfolio.html b/examples/html/portfolio.html new file mode 100644 index 0000000000..986b7330e7 --- /dev/null +++ b/examples/html/portfolio.html @@ -0,0 +1,10 @@ + + My Portfolio + + + + +
+

My Portfolio

Hello, this is my portfolio. You can also checkout the Blog
Sidebar
+
+ diff --git a/examples/src/blog.js b/examples/src/blog.js new file mode 100644 index 0000000000..4dac5d63e1 --- /dev/null +++ b/examples/src/blog.js @@ -0,0 +1,40 @@ +import { Text } from '../../components/atomic/atomic.mjs'; +import { Component } from '../../components/atomic/component.mjs'; +import { Container, Page } from '../../components/atomic/page.mjs'; +import { Button } from '../../components/button/button.mjs'; + +class Link extends Component { + constructor(options) { + super(options); + this.setTagName('a'); + //this.setAttribute('href', options.href); + } +} + +const blogPage = new Page({ + title: 'My Blog', + description: 'This is a custom blog', + keywords: 'News sites, personal journals, niche resource hubs, and content creators.', + children: [ + new Container({ children: new Text('Blog').setTagName('h1') }), + new Container({ children: 'This is a featured Post' }).addClassname('py-5'), + new Container({ + children: + '2 or 3-column masonry grid showing article thumbnails, titles, and publication dates' + }).addClassname('py-5'), + new Button({ children: 'Call to action' }), + new Link({ href: '.landingpage.html' }), + new Text( + `This is a test Landingpage. ok it can produce nested html too...
+ Or you can go to the Portfolio` + ), + new Container({ + children: 'Sidebar or navigation dropdowns ("Tech," "Lifestyle")' + }).addClassname('py-5') + ] +}).addStyleUrl( + 'https://cdn.jsdelivr.net/npm/@materializecss/materialize@latest/dist/css/materialize.min.css' +); + +const html = blogPage.toHTML(); +console.log(html); diff --git a/examples/src/landingpage.js b/examples/src/landingpage.js new file mode 100644 index 0000000000..c9a5881e1e --- /dev/null +++ b/examples/src/landingpage.js @@ -0,0 +1,27 @@ +import { Text } from '../../components/atomic/atomic.mjs'; +import { Container, Page } from '../../components/atomic/page.mjs'; + +const landingPage = new Page({ + title: 'My Landingpage', + description: 'Introducing the new Phone', + keywords: 'App launches, SaaS companies, small service businesses, and single-product e-commerce', + children: [ + new Container({ children: new Text('Landing Page').setTagName('h1') }), + new Container(``), + new Container({ + children: 'Hero Section', + description: `A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),' + + 'feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.". + You can also checkout the Blog` + }), + new Container(`A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
+ feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.
+ You can also checkout the Blog`), + new Container('Hello, this is my landing page!').addClassname('pt-5') + ] +}).addStyleUrl( + 'https://cdn.jsdelivr.net/npm/@materializecss/materialize@latest/dist/css/materialize.min.css' +); + +const html = landingPage.toHTML(); +console.log(html); diff --git a/examples/src/portfolio.js b/examples/src/portfolio.js new file mode 100644 index 0000000000..dd62ac97f5 --- /dev/null +++ b/examples/src/portfolio.js @@ -0,0 +1,31 @@ +import { Text } from '../../components/atomic/atomic.mjs'; +import { Container, Page } from '../../components/atomic/page.mjs'; +import { Grid } from '../../components/grid/grid.js'; + +const portfolioPage = new Page({ + title: 'My Portfolio', + description: 'This is a custom gallery of my items', + keywords: 'Gallery, Products, Stuff', + children: [ + new Container({ children: new Text('My Portfolio').setTagName('h1') }), + new Container( + `Hello, this is my portfolio. You can also checkout the Blog` + ).addClassname('pb-5'), + new Container({ children: 'Sidebar' }), + new Grid({ + children: [ + ``, + ``, + ``, + `` + ] + }) + .setColumns(2) + .addClassname('py-5') + ] +}).addStyleUrl( + 'https://cdn.jsdelivr.net/npm/@materializecss/materialize@latest/dist/css/materialize.min.css' +); + +const html = portfolioPage.toHTML(); +console.log(html); diff --git a/index.html b/index.html index a104bce7ad..81fb6a6486 100644 --- a/index.html +++ b/index.html @@ -44,24 +44,28 @@
Textfields
+
Middle Name
+
Family Name
+
Birthmonth
+
Gender @@ -71,6 +75,7 @@
Textfields
+
Height @@ -89,6 +94,7 @@
Textfields
+
Budget @@ -96,6 +102,7 @@
Textfields
+
Birthday diff --git a/package-lock.json b/package-lock.json index 46fca34b48..6e7f6b9449 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,20 +51,20 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", - "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", "dev": true, "license": "MIT" }, "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -73,9 +73,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -83,9 +83,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "dev": true, "license": "MIT", "peer": true, @@ -697,29 +697,43 @@ } }, "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.1", + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1273,9 +1287,9 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", - "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", + "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==", "dev": true, "license": "MIT", "dependencies": { @@ -1296,9 +1310,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", - "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", "cpu": [ "arm" ], @@ -1310,9 +1324,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", - "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", "cpu": [ "arm64" ], @@ -1324,9 +1338,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", - "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", "cpu": [ "arm64" ], @@ -1338,9 +1352,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", - "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", "cpu": [ "x64" ], @@ -1352,9 +1366,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", - "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", "cpu": [ "arm64" ], @@ -1366,9 +1380,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", - "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", "cpu": [ "x64" ], @@ -1380,9 +1394,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", - "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", "cpu": [ "arm" ], @@ -1397,9 +1411,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", - "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", "cpu": [ "arm" ], @@ -1414,9 +1428,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", - "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", "cpu": [ "arm64" ], @@ -1431,9 +1445,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", - "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", "cpu": [ "arm64" ], @@ -1448,9 +1462,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", - "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", "cpu": [ "loong64" ], @@ -1465,9 +1479,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", - "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", "cpu": [ "loong64" ], @@ -1482,9 +1496,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", - "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", "cpu": [ "ppc64" ], @@ -1499,9 +1513,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", - "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", "cpu": [ "ppc64" ], @@ -1516,9 +1530,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", - "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", "cpu": [ "riscv64" ], @@ -1533,9 +1547,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", - "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", "cpu": [ "riscv64" ], @@ -1550,9 +1564,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", - "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", "cpu": [ "s390x" ], @@ -1567,9 +1581,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", - "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", "cpu": [ "x64" ], @@ -1584,9 +1598,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", - "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", "cpu": [ "x64" ], @@ -1601,9 +1615,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", - "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", "cpu": [ "x64" ], @@ -1615,9 +1629,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", - "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", "cpu": [ "arm64" ], @@ -1629,9 +1643,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", - "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", "cpu": [ "arm64" ], @@ -1643,9 +1657,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", - "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", "cpu": [ "ia32" ], @@ -1657,9 +1671,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", - "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", "cpu": [ "x64" ], @@ -1671,9 +1685,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", - "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", "cpu": [ "x64" ], @@ -1935,9 +1949,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "dev": true, "license": "MIT" }, @@ -1970,9 +1984,9 @@ "license": "MIT" }, "node_modules/@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.14.tgz", + "integrity": "sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==", "dev": true, "license": "MIT" }, @@ -1984,9 +1998,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz", - "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==", + "version": "20.19.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", + "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", "dev": true, "license": "MIT", "dependencies": { @@ -1994,9 +2008,9 @@ } }, "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "dev": true, "license": "MIT", "peer": true, @@ -2005,17 +2019,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.1.tgz", - "integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.1.tgz", + "integrity": "sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.58.1", - "@typescript-eslint/type-utils": "8.58.1", - "@typescript-eslint/utils": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1", + "@typescript-eslint/scope-manager": "8.62.1", + "@typescript-eslint/type-utils": "8.62.1", + "@typescript-eslint/utils": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -2028,7 +2042,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.58.1", + "@typescript-eslint/parser": "^8.62.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -2044,16 +2058,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.1.tgz", - "integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", + "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1", + "@typescript-eslint/scope-manager": "8.62.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/typescript-estree": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1", "debug": "^4.4.3" }, "engines": { @@ -2069,14 +2083,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.1.tgz", - "integrity": "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", + "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.58.1", - "@typescript-eslint/types": "^8.58.1", + "@typescript-eslint/tsconfig-utils": "^8.62.1", + "@typescript-eslint/types": "^8.62.1", "debug": "^4.4.3" }, "engines": { @@ -2091,14 +2105,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.1.tgz", - "integrity": "sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", + "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1" + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2109,9 +2123,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.1.tgz", - "integrity": "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", + "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", "dev": true, "license": "MIT", "engines": { @@ -2126,15 +2140,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.1.tgz", - "integrity": "sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz", + "integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1", - "@typescript-eslint/utils": "8.58.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/typescript-estree": "8.62.1", + "@typescript-eslint/utils": "8.62.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2151,9 +2165,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.1.tgz", - "integrity": "sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", + "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -2165,16 +2179,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.1.tgz", - "integrity": "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", + "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.58.1", - "@typescript-eslint/tsconfig-utils": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/visitor-keys": "8.58.1", + "@typescript-eslint/project-service": "8.62.1", + "@typescript-eslint/tsconfig-utils": "8.62.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/visitor-keys": "8.62.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2203,9 +2217,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", "dev": true, "license": "MIT", "dependencies": { @@ -2232,16 +2246,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.1.tgz", - "integrity": "sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.1.tgz", + "integrity": "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.58.1", - "@typescript-eslint/types": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1" + "@typescript-eslint/scope-manager": "8.62.1", + "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/typescript-estree": "8.62.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2256,13 +2270,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.1.tgz", - "integrity": "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", + "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/types": "8.62.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2354,13 +2368,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.4.tgz", - "integrity": "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.4", + "@vitest/utils": "4.1.10", "pathe": "^2.0.3" }, "funding": { @@ -2368,9 +2382,9 @@ } }, "node_modules/@vitest/runner/node_modules/@vitest/pretty-format": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz", - "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2381,13 +2395,13 @@ } }, "node_modules/@vitest/runner/node_modules/@vitest/utils": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz", - "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.4", + "@vitest/pretty-format": "4.1.10", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2406,14 +2420,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.4.tgz", - "integrity": "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.4", - "@vitest/utils": "4.1.4", + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -2422,9 +2436,9 @@ } }, "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz", - "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2435,13 +2449,13 @@ } }, "node_modules/@vitest/snapshot/node_modules/@vitest/utils": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz", - "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.4", + "@vitest/pretty-format": "4.1.10", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2515,9 +2529,9 @@ } }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "license": "MIT", "bin": { @@ -2538,9 +2552,9 @@ } }, "node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -2683,9 +2697,9 @@ "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.27", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.27.tgz", - "integrity": "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==", + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz", + "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==", "dev": true, "funding": [ { @@ -2703,8 +2717,8 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.28.1", - "caniuse-lite": "^1.0.30001774", + "browserslist": "^4.28.4", + "caniuse-lite": "^1.0.30001799", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" @@ -2720,9 +2734,9 @@ } }, "node_modules/b4a": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", - "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz", + "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -2742,9 +2756,9 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz", + "integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -2757,9 +2771,9 @@ } }, "node_modules/bare-fs": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.0.tgz", - "integrity": "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.3.tgz", + "integrity": "sha512-xRgplks8SvcKkdlv2M6Z2LZmRsmqd+x0nXXGXeMEjwdibj1HSDrlnqBRLeYdMvsgCox7Bq0e+DHwfczOfsn6IA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2782,9 +2796,9 @@ } }, "node_modules/bare-os": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.7.tgz", - "integrity": "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.3.tgz", + "integrity": "sha512-fF4Q7QsyKVF5Rj0qvI8BgUNjqzC2JvQlpTaPLjVJVxYVUX5Zr9un+y3w1HmA4nNKdFmRBT8z/WmrjvXzXVerKQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2792,9 +2806,9 @@ } }, "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.1.tgz", + "integrity": "sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2802,12 +2816,13 @@ } }, "node_modules/bare-stream": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.0.tgz", - "integrity": "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==", + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.3.tgz", + "integrity": "sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==", "dev": true, "license": "Apache-2.0", "dependencies": { + "b4a": "^1.8.1", "streamx": "^2.25.0", "teex": "^1.0.1" }, @@ -2829,9 +2844,9 @@ } }, "node_modules/bare-url": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.0.tgz", - "integrity": "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.5.tgz", + "integrity": "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2860,9 +2875,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.18", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.18.tgz", - "integrity": "sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==", + "version": "2.10.42", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", + "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2886,9 +2901,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", "dev": true, "license": "MIT", "dependencies": { @@ -2900,7 +2915,7 @@ "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", - "qs": "~6.14.0", + "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" @@ -2928,9 +2943,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -2952,9 +2967,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz", + "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==", "dev": true, "funding": [ { @@ -2972,10 +2987,10 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", + "baseline-browser-mapping": "^2.10.38", + "caniuse-lite": "^1.0.30001799", + "electron-to-chromium": "^1.5.376", + "node-releases": "^2.0.48", "update-browserslist-db": "^1.2.3" }, "bin": { @@ -3079,9 +3094,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001787", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001787.tgz", - "integrity": "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==", + "version": "1.0.30001802", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001802.tgz", + "integrity": "sha512-vmv8ub2xwTNmljSKf82mtCk5JH7hC+YgzLj3P5zotvA0tPQ9016tdNNOG8WRca1IxOnhSsivB+J0z5FeE5LOUw==", "dev": true, "funding": [ { @@ -3144,16 +3159,16 @@ } }, "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", "dev": true, "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "readdirp": "^5.0.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -3482,9 +3497,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.335", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.335.tgz", - "integrity": "sha512-q9n5T4BR4Xwa2cwbrwcsDJtHD/enpQ5S1xF1IAtdqf5AAgqDFmR/aakqH3ChFdqd/QXJhS3rnnXFtexU7rax6Q==", + "version": "1.5.387", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.387.tgz", + "integrity": "sha512-TaxwufTFDufvPEoXdhwVrA3UdFWBeWGkYoJ1K8ldF1xe6gKfth6iRNS5lTQ5JPNOHdGQm8PT1QYKUqFLCiUefQ==", "dev": true, "license": "ISC" }, @@ -3526,16 +3541,16 @@ } }, "node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.0.tgz", + "integrity": "sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==", "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -3863,9 +3878,9 @@ } }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3873,15 +3888,15 @@ } }, "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "~1.20.3", + "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", @@ -3900,7 +3915,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "~6.14.0", + "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", @@ -4046,9 +4061,9 @@ } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "license": "MIT", "dependencies": { @@ -4328,9 +4343,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "license": "MIT", "dependencies": { @@ -4452,9 +4467,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, "license": "MIT", "dependencies": { @@ -4537,9 +4552,9 @@ "license": "MIT" }, "node_modules/immutable": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz", + "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==", "dev": true, "license": "MIT" }, @@ -4610,13 +4625,13 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -4816,10 +4831,20 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -5204,9 +5229,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", "dev": true, "funding": [ { @@ -5248,11 +5273,14 @@ "optional": true }, "node_modules/node-releases": { - "version": "2.0.37", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", - "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5284,15 +5312,18 @@ } }, "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } }, "node_modules/on-finished": { "version": "2.4.1", @@ -5518,9 +5549,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { @@ -5531,9 +5562,9 @@ } }, "node_modules/postcss": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz", - "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==", + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", "dev": true, "funding": [ { @@ -5551,7 +5582,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -5648,13 +5679,14 @@ } }, "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -5711,9 +5743,9 @@ } }, "node_modules/react": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", - "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "dev": true, "license": "MIT", "engines": { @@ -5721,16 +5753,16 @@ } }, "node_modules/react-dom": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", - "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "dev": true, "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.5" + "react": "^19.2.7" } }, "node_modules/react-is": { @@ -5769,9 +5801,9 @@ } }, "node_modules/readdir-glob/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "license": "MIT", "dependencies": { @@ -5792,13 +5824,13 @@ } }, "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 14.18.0" + "node": ">= 20.19.0" }, "funding": { "type": "individual", @@ -5806,9 +5838,9 @@ } }, "node_modules/recast": { - "version": "0.23.11", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", - "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "version": "0.23.12", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.12.tgz", + "integrity": "sha512-dEWRjcINDu/F4l2dYx57ugBtD7HV9KXESyxhzw/MqWLeglJrsjJKqACPyUPg+6AF8mIgm+Zi0dZ3ACoIg+QtpA==", "dev": true, "license": "MIT", "dependencies": { @@ -5880,13 +5912,13 @@ } }, "node_modules/rollup": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", - "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" + "@types/estree": "1.0.9" }, "bin": { "rollup": "dist/bin/rollup" @@ -5896,31 +5928,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.1", - "@rollup/rollup-android-arm64": "4.60.1", - "@rollup/rollup-darwin-arm64": "4.60.1", - "@rollup/rollup-darwin-x64": "4.60.1", - "@rollup/rollup-freebsd-arm64": "4.60.1", - "@rollup/rollup-freebsd-x64": "4.60.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", - "@rollup/rollup-linux-arm-musleabihf": "4.60.1", - "@rollup/rollup-linux-arm64-gnu": "4.60.1", - "@rollup/rollup-linux-arm64-musl": "4.60.1", - "@rollup/rollup-linux-loong64-gnu": "4.60.1", - "@rollup/rollup-linux-loong64-musl": "4.60.1", - "@rollup/rollup-linux-ppc64-gnu": "4.60.1", - "@rollup/rollup-linux-ppc64-musl": "4.60.1", - "@rollup/rollup-linux-riscv64-gnu": "4.60.1", - "@rollup/rollup-linux-riscv64-musl": "4.60.1", - "@rollup/rollup-linux-s390x-gnu": "4.60.1", - "@rollup/rollup-linux-x64-gnu": "4.60.1", - "@rollup/rollup-linux-x64-musl": "4.60.1", - "@rollup/rollup-openbsd-x64": "4.60.1", - "@rollup/rollup-openharmony-arm64": "4.60.1", - "@rollup/rollup-win32-arm64-msvc": "4.60.1", - "@rollup/rollup-win32-ia32-msvc": "4.60.1", - "@rollup/rollup-win32-x64-gnu": "4.60.1", - "@rollup/rollup-win32-x64-msvc": "4.60.1", + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", "fsevents": "~2.3.2" } }, @@ -6047,13 +6079,13 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.99.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz", - "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", + "version": "1.101.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", + "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", "dev": true, "license": "MIT", "dependencies": { - "chokidar": "^4.0.0", + "chokidar": "^5.0.0", "immutable": "^5.1.5", "source-map-js": ">=0.6.2 <2.0.0" }, @@ -6061,7 +6093,7 @@ "sass": "sass.js" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.19.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" @@ -6075,9 +6107,9 @@ "license": "MIT" }, "node_modules/selenium-webdriver": { - "version": "4.43.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.43.0.tgz", - "integrity": "sha512-dV4zBTT37or3Z3/8uD6rS8zvd4ZxPuG4EJVlqYIbZCGZCYttZm7xb9rlFLSk4rrsQHAeDYvudl7cquo0vWpHjg==", + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.45.0.tgz", + "integrity": "sha512-Cb2nqvJiwXVOtRTCYHX9D1FJR5+Ls7aL3Nev0t6n4CpXsQ//YGiiUmSCbvTDDeLtbV85SZ46qmLab4SIYKXWRw==", "dev": true, "funding": [ { @@ -6093,17 +6125,17 @@ "dependencies": { "@bazel/runfiles": "^6.5.0", "jszip": "^3.10.1", - "tmp": "^0.2.5", - "ws": "^8.20.0" + "tmp": "^0.2.7", + "ws": "^8.21.0" }, "engines": { "node": ">= 20.0.0" } }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -6156,9 +6188,9 @@ "license": "MIT" }, "node_modules/serialize-javascript": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", - "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.7.tgz", + "integrity": "sha512-YAy8Od6KV+uuwUuU50np8fGB/Aues6Y0nAhA9y/hId74PlKUcme4pXcBD46NWKr1Q4osN/iseZ17YqO1XfmI8g==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -6219,15 +6251,15 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -6325,9 +6357,9 @@ } }, "node_modules/smob": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.1.tgz", - "integrity": "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz", + "integrity": "sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==", "dev": true, "license": "MIT", "engines": { @@ -6383,9 +6415,9 @@ } }, "node_modules/std-env": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", - "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", "dev": true, "license": "MIT" }, @@ -6426,9 +6458,9 @@ } }, "node_modules/streamx": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz", - "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==", + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.0.tgz", + "integrity": "sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==", "dev": true, "license": "MIT", "dependencies": { @@ -6597,9 +6629,9 @@ } }, "node_modules/tar-stream": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", - "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", + "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", "dev": true, "license": "MIT", "dependencies": { @@ -6620,9 +6652,9 @@ } }, "node_modules/terser": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", - "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", + "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6663,9 +6695,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz", - "integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", "dev": true, "license": "MIT", "engines": { @@ -6673,9 +6705,9 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", "dependencies": { @@ -6710,9 +6742,9 @@ } }, "node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", "dev": true, "license": "MIT", "engines": { @@ -6756,9 +6788,9 @@ } }, "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.3.0.tgz", + "integrity": "sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==", "dev": true, "license": "MIT", "engines": { @@ -6814,16 +6846,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.58.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.58.1.tgz", - "integrity": "sha512-gf6/oHChByg9HJvhMO1iBexJh12AqqTfnuxscMDOVqfJW3htsdRJI/GfPpHTTcyeB8cSTUY2JcZmVgoyPqcrDg==", + "version": "8.62.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.1.tgz", + "integrity": "sha512-vymnnM5g0AKQDSAyfP12nMIBvgwgA42syg74kkuZ4x1VuTzwQKwc5h9rGxeShCjny5o+zWAb6OEoz7XLgrIkIw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.58.1", - "@typescript-eslint/parser": "8.58.1", - "@typescript-eslint/typescript-estree": "8.58.1", - "@typescript-eslint/utils": "8.58.1" + "@typescript-eslint/eslint-plugin": "8.62.1", + "@typescript-eslint/parser": "8.62.1", + "@typescript-eslint/typescript-estree": "8.62.1", + "@typescript-eslint/utils": "8.62.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6947,13 +6979,13 @@ } }, "node_modules/vite": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", - "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", + "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -7022,9 +7054,9 @@ } }, "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ "ppc64" ], @@ -7039,9 +7071,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], @@ -7056,9 +7088,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], @@ -7073,9 +7105,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ "x64" ], @@ -7090,9 +7122,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ "arm64" ], @@ -7107,9 +7139,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ "x64" ], @@ -7124,9 +7156,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ "arm64" ], @@ -7141,9 +7173,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ "x64" ], @@ -7158,9 +7190,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ "arm" ], @@ -7175,9 +7207,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ "arm64" ], @@ -7192,9 +7224,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ "ia32" ], @@ -7209,9 +7241,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ "loong64" ], @@ -7226,9 +7258,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ "mips64el" ], @@ -7243,9 +7275,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ "ppc64" ], @@ -7260,9 +7292,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ "riscv64" ], @@ -7277,9 +7309,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ "s390x" ], @@ -7294,9 +7326,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], @@ -7311,9 +7343,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], @@ -7328,9 +7360,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], @@ -7345,9 +7377,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], @@ -7362,9 +7394,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], @@ -7379,9 +7411,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ "arm64" ], @@ -7396,9 +7428,9 @@ } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ "x64" ], @@ -7413,9 +7445,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -7430,9 +7462,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -7447,9 +7479,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -7464,9 +7496,9 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -7477,48 +7509,48 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" } }, "node_modules/vitest": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.4.tgz", - "integrity": "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.4", - "@vitest/mocker": "4.1.4", - "@vitest/pretty-format": "4.1.4", - "@vitest/runner": "4.1.4", - "@vitest/snapshot": "4.1.4", - "@vitest/spy": "4.1.4", - "@vitest/utils": "4.1.4", + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -7546,12 +7578,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.4", - "@vitest/browser-preview": "4.1.4", - "@vitest/browser-webdriverio": "4.1.4", - "@vitest/coverage-istanbul": "4.1.4", - "@vitest/coverage-v8": "4.1.4", - "@vitest/ui": "4.1.4", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -7596,16 +7628,16 @@ } }, "node_modules/vitest/node_modules/@vitest/expect": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.4.tgz", - "integrity": "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.4", - "@vitest/utils": "4.1.4", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -7614,13 +7646,13 @@ } }, "node_modules/vitest/node_modules/@vitest/mocker": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.4.tgz", - "integrity": "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.4", + "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -7641,9 +7673,9 @@ } }, "node_modules/vitest/node_modules/@vitest/pretty-format": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz", - "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7654,9 +7686,9 @@ } }, "node_modules/vitest/node_modules/@vitest/spy": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.4.tgz", - "integrity": "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", "dev": true, "license": "MIT", "funding": { @@ -7664,13 +7696,13 @@ } }, "node_modules/vitest/node_modules/@vitest/utils": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz", - "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.4", + "@vitest/pretty-format": "4.1.10", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -7851,9 +7883,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", - "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "dev": true, "license": "MIT", "engines": { From 2faa93bdf4ac0826457283e46580647fbb6decc4 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Mon, 6 Jul 2026 15:49:14 +0200 Subject: [PATCH 04/60] docs: cleaned headings --- README.md | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index d155fe06fd..0ebfaf4bdc 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@

## Getting started + Read the [getting started guide](https://materializeweb.com/getting-started.html) for more information on how to use materialize. - [Download the latest release](https://github.com/materializecss/materialize/releases/latest) of materialize directly from GitHub. ([Beta](https://github.com/materializecss/materialize/releases/)) @@ -37,40 +38,31 @@ Read the [getting started guide](https://materializeweb.com/getting-started.html - Include the files via [jsDelivr](https://www.jsdelivr.com/package/npm/@materializecss/materialize). - Install with [npm](https://www.npmjs.com): `npm install @materializecss/materialize` (Beta: `npm install @materializecss/materialize@next`) -## Testing +### Releases + +Previous releases are available [here](https://github.com/materializecss/materialize/releases). You can also find the changelog under each release. + +## Test + To run tests locally you first have to build the files and then run the tests. This can be done with the command `npm test`; To get more info and debug information you can do the following: run `npx jasmine-browser-runner` then go to the url via browser `http://localhost:8888`. The tests will then run and show detailed feedback. -## Development -The documentation can be found at . To run the documentation locally on your machine, you need [Node.js](https://nodejs.org) installed on your computer. -This is the core project with all the components. To see how they are used we recommend using an example project or go to the documentation. - -### Running documentation locally -See [Materialize Docs Repo](https://github.com/materializecss/materialize-docs) to see Materialize in Action. +We use Jasmine as our testing framework and we're trying to write a robust test suite for our components. If you want to help, [here's a starting guide on how to write tests in Jasmine](docs/CONTRIBUTING.md#jasmine-testing-guide). -### Releases -Previous releases are available [here](https://github.com/materializecss/materialize/releases). You can also find the changelog under each release. +For quick testing install live-server node package globally and run `npm run demo` -## Supported Browsers: -Materialize is compatible with: +## Develop -- Chrome 35+ -- Firefox 31+ -- Safari 9+ -- Opera -- Edge +The documentation can be found at . To run the documentation locally on your machine, you need [Node.js](https://nodejs.org) installed on your computer. +This is the core project with all the components. To see how they are used we recommend using an example project or go to the documentation. -## Testing -We use Jasmine as our testing framework and we're trying to write a robust test suite for our components. If you want to help, [here's a starting guide on how to write tests in Jasmine](docs/CONTRIBUTING.md#jasmine-testing-guide). +See [Materialize Docs Repo](https://github.com/materializecss/materialize-docs) to see Materialize in Action and to read the documentation. -## Quick Testing and Development -For quick testing install live-server node package globally and run `npm run demo` +## Contribute -## Contributing Check out the [CONTRIBUTING document](docs/CONTRIBUTING.md) in the root of the repository to learn how you can contribute. You can also browse the [help-wanted](https://github.com/materializecss/materialize/labels/help-wanted) tag in our issue tracker to find things to do. -## Sponsors Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/materialize#sponsor)] [![OC sponsor 0](https://opencollective.com/materialize/sponsor/0/avatar.svg)](https://opencollective.com/materialize/sponsor/0/website) @@ -84,11 +76,10 @@ Support this project by becoming a sponsor. Your logo will show up here with a l [![OC sponsor 8](https://opencollective.com/materialize/sponsor/8/avatar.svg)](https://opencollective.com/materialize/sponsor/8/website) [![OC sponsor 9](https://opencollective.com/materialize/sponsor/9/avatar.svg)](https://opencollective.com/materialize/sponsor/9/website) - -## Backers -Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/materialize#backer)] +Thank you to all our supporters! 🙏 [[Become a backer](https://opencollective.com/materialize#backer)] [![Backers](https://opencollective.com/materialize/backers.svg?width=890)](https://opencollective.com/materialize#backers) ## Copyright and license + Code Copyright 2026 Materialize. Code released under the MIT license. From 0bac247dd2e1020491732381d266643490cf7be1 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 8 Jul 2026 12:19:56 +0200 Subject: [PATCH 05/60] refactor: remove dist folder --- dist/.gitkeep | 0 dist/css/materialize.colors.min.css | 6 - dist/css/materialize.css | 7900 ------------------------- dist/css/materialize.min.css | 6 - dist/css/materialize.min.css.map | 1 - dist/js/materialize.cjs.js | 8404 -------------------------- dist/js/materialize.d.ts | 2625 --------- dist/js/materialize.js | 8409 --------------------------- dist/js/materialize.min.js | 6 - dist/js/materialize.mjs | 8376 -------------------------- 10 files changed, 35733 deletions(-) delete mode 100644 dist/.gitkeep delete mode 100644 dist/css/materialize.colors.min.css delete mode 100644 dist/css/materialize.css delete mode 100644 dist/css/materialize.min.css delete mode 100644 dist/css/materialize.min.css.map delete mode 100644 dist/js/materialize.cjs.js delete mode 100644 dist/js/materialize.d.ts delete mode 100644 dist/js/materialize.js delete mode 100644 dist/js/materialize.min.js delete mode 100644 dist/js/materialize.mjs diff --git a/dist/.gitkeep b/dist/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/dist/css/materialize.colors.min.css b/dist/css/materialize.colors.min.css deleted file mode 100644 index 7e3544c9d4..0000000000 --- a/dist/css/materialize.colors.min.css +++ /dev/null @@ -1,6 +0,0 @@ -/*! -* Materialize v2.3.3 (https://materializeweb.com) -* Copyright 2014-2026 Materialize -* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE) -*/ -.materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#f44336 !important}.red-text{color:#f44336 !important}.red.lighten-5{background-color:#ffebee !important}.red-text.text-lighten-5{color:#ffebee !important}.red.lighten-4{background-color:#ffcdd2 !important}.red-text.text-lighten-4{color:#ffcdd2 !important}.red.lighten-3{background-color:#ef9a9a !important}.red-text.text-lighten-3{color:#ef9a9a !important}.red.lighten-2{background-color:#e57373 !important}.red-text.text-lighten-2{color:#e57373 !important}.red.lighten-1{background-color:#ef5350 !important}.red-text.text-lighten-1{color:#ef5350 !important}.red.darken-1{background-color:#e53935 !important}.red-text.text-darken-1{color:#e53935 !important}.red.darken-2{background-color:#d32f2f !important}.red-text.text-darken-2{color:#d32f2f !important}.red.darken-3{background-color:#c62828 !important}.red-text.text-darken-3{color:#c62828 !important}.red.darken-4{background-color:#b71c1c !important}.red-text.text-darken-4{color:#b71c1c !important}.red.accent-1{background-color:#ff8a80 !important}.red-text.text-accent-1{color:#ff8a80 !important}.red.accent-2{background-color:#ff5252 !important}.red-text.text-accent-2{color:#ff5252 !important}.red.accent-3{background-color:#ff1744 !important}.red-text.text-accent-3{color:#ff1744 !important}.red.accent-4{background-color:#d50000 !important}.red-text.text-accent-4{color:#d50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196f3 !important}.blue-text{color:#2196f3 !important}.blue.lighten-5{background-color:#e3f2fd !important}.blue-text.text-lighten-5{color:#e3f2fd !important}.blue.lighten-4{background-color:#bbdefb !important}.blue-text.text-lighten-4{color:#bbdefb !important}.blue.lighten-3{background-color:#90caf9 !important}.blue-text.text-lighten-3{color:#90caf9 !important}.blue.lighten-2{background-color:#64b5f6 !important}.blue-text.text-lighten-2{color:#64b5f6 !important}.blue.lighten-1{background-color:#42a5f5 !important}.blue-text.text-lighten-1{color:#42a5f5 !important}.blue.darken-1{background-color:#1e88e5 !important}.blue-text.text-darken-1{color:#1e88e5 !important}.blue.darken-2{background-color:#1976d2 !important}.blue-text.text-darken-2{color:#1976d2 !important}.blue.darken-3{background-color:#1565c0 !important}.blue-text.text-darken-3{color:#1565c0 !important}.blue.darken-4{background-color:#0d47a1 !important}.blue-text.text-darken-4{color:#0d47a1 !important}.blue.accent-1{background-color:#82b1ff !important}.blue-text.text-accent-1{color:#82b1ff !important}.blue.accent-2{background-color:#448aff !important}.blue-text.text-accent-2{color:#448aff !important}.blue.accent-3{background-color:#2979ff !important}.blue-text.text-accent-3{color:#2979ff !important}.blue.accent-4{background-color:#2962ff !important}.blue-text.text-accent-4{color:#2962ff !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4caf50 !important}.green-text{color:#4caf50 !important}.green.lighten-5{background-color:#e8f5e9 !important}.green-text.text-lighten-5{color:#e8f5e9 !important}.green.lighten-4{background-color:#c8e6c9 !important}.green-text.text-lighten-4{color:#c8e6c9 !important}.green.lighten-3{background-color:#a5d6a7 !important}.green-text.text-lighten-3{color:#a5d6a7 !important}.green.lighten-2{background-color:#81c784 !important}.green-text.text-lighten-2{color:#81c784 !important}.green.lighten-1{background-color:#66bb6a !important}.green-text.text-lighten-1{color:#66bb6a !important}.green.darken-1{background-color:#43a047 !important}.green-text.text-darken-1{color:#43a047 !important}.green.darken-2{background-color:#388e3c !important}.green-text.text-darken-2{color:#388e3c !important}.green.darken-3{background-color:#2e7d32 !important}.green-text.text-darken-3{color:#2e7d32 !important}.green.darken-4{background-color:#1b5e20 !important}.green-text.text-darken-4{color:#1b5e20 !important}.green.accent-1{background-color:#b9f6ca !important}.green-text.text-accent-1{color:#b9f6ca !important}.green.accent-2{background-color:#69f0ae !important}.green-text.text-accent-2{color:#69f0ae !important}.green.accent-3{background-color:#00e676 !important}.green-text.text-accent-3{color:#00e676 !important}.green.accent-4{background-color:#00c853 !important}.green-text.text-accent-4{color:#00c853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:rgba(0,0,0,0) !important}.transparent-text{color:rgba(0,0,0,0) !important} \ No newline at end of file diff --git a/dist/css/materialize.css b/dist/css/materialize.css deleted file mode 100644 index 0e1ef2f3b8..0000000000 --- a/dist/css/materialize.css +++ /dev/null @@ -1,7900 +0,0 @@ -/*! -* Materialize v2.3.3 (https://materializeweb.com) -* Copyright 2014-2026 Materialize -* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE) -*/ -@charset "UTF-8"; -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ -/* Document - ========================================================================== */ -/** - * 1. Correct the line height in all browsers. - * 2. Prevent adjustments of font size after orientation changes in iOS. - */ -html { - line-height: 1.15; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/* Sections - ========================================================================== */ -/** - * Remove the margin in all browsers. - */ -body { - margin: 0; -} - -/** - * Render the `main` element consistently in IE. - */ -main { - display: block; -} - -/** - * Correct the font size and margin on `h1` elements within `section` and - * `article` contexts in Chrome, Firefox, and Safari. - */ -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/* Grouping content - ========================================================================== */ -/** - * 1. Add the correct box sizing in Firefox. - * 2. Show the overflow in Edge and IE. - */ -hr { - -webkit-box-sizing: content-box; - box-sizing: content-box; /* 1 */ - height: 0; /* 1 */ - overflow: visible; /* 2 */ -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ -pre { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/* Text-level semantics - ========================================================================== */ -/** - * Remove the gray background on active links in IE 10. - */ -a { - background-color: transparent; -} - -/** - * 1. Remove the bottom border in Chrome 57- - * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. - */ -abbr[title] { - border-bottom: none; /* 1 */ - text-decoration: underline; /* 2 */ - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; /* 2 */ -} - -/** - * Add the correct font weight in Chrome, Edge, and Safari. - */ -b, -strong { - font-weight: bolder; -} - -/** - * 1. Correct the inheritance and scaling of font size in all browsers. - * 2. Correct the odd `em` font sizing in all browsers. - */ -code, -kbd, -samp { - font-family: monospace, monospace; /* 1 */ - font-size: 1em; /* 2 */ -} - -/** - * Add the correct font size in all browsers. - */ -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` elements from affecting the line height in - * all browsers. - */ -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* Embedded content - ========================================================================== */ -/** - * Remove the border on images inside links in IE 10. - */ -img { - border-style: none; -} - -/* Forms - ========================================================================== */ -/** - * 1. Change the font styles in all browsers. - * 2. Remove the margin in Firefox and Safari. - */ -button, -input, -optgroup, -select, -textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 1 */ - line-height: 1.15; /* 1 */ - margin: 0; /* 2 */ -} - -/** - * Show the overflow in IE. - * 1. Show the overflow in Edge. - */ -button, -input { /* 1 */ - overflow: visible; -} - -/** - * Remove the inheritance of text transform in Edge, Firefox, and IE. - * 1. Remove the inheritance of text transform in Firefox. - */ -button, -select { /* 1 */ - text-transform: none; -} - -/** - * Correct the inability to style clickable types in iOS and Safari. - */ -button, -[type=button], -[type=reset], -[type=submit] { - -webkit-appearance: button; -} - -/** - * Remove the inner border and padding in Firefox. - */ -button::-moz-focus-inner, -[type=button]::-moz-focus-inner, -[type=reset]::-moz-focus-inner, -[type=submit]::-moz-focus-inner { - border-style: none; - padding: 0; -} - -/** - * Restore the focus styles unset by the previous rule. - */ -button:-moz-focusring, -[type=button]:-moz-focusring, -[type=reset]:-moz-focusring, -[type=submit]:-moz-focusring { - outline: 1px dotted ButtonText; -} - -/** - * Correct the padding in Firefox. - */ -fieldset { - padding: 0.35em 0.75em 0.625em; -} - -/** - * 1. Correct the text wrapping in Edge and IE. - * 2. Correct the color inheritance from `fieldset` elements in IE. - * 3. Remove the padding so developers are not caught out when they zero out - * `fieldset` elements in all browsers. - */ -legend { - -webkit-box-sizing: border-box; - box-sizing: border-box; /* 1 */ - color: inherit; /* 2 */ - display: table; /* 1 */ - max-width: 100%; /* 1 */ - padding: 0; /* 3 */ - white-space: normal; /* 1 */ -} - -/** - * Add the correct vertical alignment in Chrome, Firefox, and Opera. - */ -progress { - vertical-align: baseline; -} - -/** - * Remove the default vertical scrollbar in IE 10+. - */ -textarea { - overflow: auto; -} - -/** - * 1. Add the correct box sizing in IE 10. - * 2. Remove the padding in IE 10. - */ -[type=checkbox], -[type=radio] { - -webkit-box-sizing: border-box; - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Correct the cursor style of increment and decrement buttons in Chrome. - */ -[type=number]::-webkit-inner-spin-button, -[type=number]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Correct the odd appearance in Chrome and Safari. - * 2. Correct the outline style in Safari. - */ -[type=search] { - -webkit-appearance: textfield; /* 1 */ - outline-offset: -2px; /* 2 */ -} - -/** - * Remove the inner padding in Chrome and Safari on macOS. - */ -[type=search]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * 1. Correct the inability to style clickable types in iOS and Safari. - * 2. Change font properties to `inherit` in Safari. - */ -::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ - font: inherit; /* 2 */ -} - -/* Interactive - ========================================================================== */ -/* - * Add the correct display in Edge, IE 10+, and Firefox. - */ -details { - display: block; -} - -/* - * Add the correct display in all browsers. - */ -summary { - display: list-item; -} - -/* Misc - ========================================================================== */ -/** - * Add the correct display in IE 10+. - */ -template { - display: none; -} - -/** - * Add the correct display in IE 10. - */ -[hidden] { - display: none; -} - -:root { - --md-source: #006495; - /* primary */ - --md-ref-palette-primary0: #000000; - --md-ref-palette-primary10: #001e30; - --md-ref-palette-primary20: #003450; - --md-ref-palette-primary25: #003f60; - --md-ref-palette-primary30: #004b71; - --md-ref-palette-primary35: #005783; - --md-ref-palette-primary40: #006495; - --md-ref-palette-primary50: #0f7eb8; - --md-ref-palette-primary60: #3d98d4; - --md-ref-palette-primary70: #5db3f0; - --md-ref-palette-primary80: #8fcdff; - --md-ref-palette-primary90: #cbe6ff; - --md-ref-palette-primary95: #e6f2ff; - --md-ref-palette-primary98: #f7f9ff; - --md-ref-palette-primary99: #fcfcff; - --md-ref-palette-primary100: #ffffff; - /* secondary */ - --md-ref-palette-secondary0: #000000; - --md-ref-palette-secondary10: #0d1d29; - --md-ref-palette-secondary20: #22323f; - --md-ref-palette-secondary25: #2d3d4b; - --md-ref-palette-secondary30: #394856; - --md-ref-palette-secondary35: #445462; - --md-ref-palette-secondary40: #50606f; - --md-ref-palette-secondary50: #697988; - --md-ref-palette-secondary60: #8293a2; - --md-ref-palette-secondary70: #9dadbd; - --md-ref-palette-secondary80: #b8c8d9; - --md-ref-palette-secondary90: #d4e4f6; - --md-ref-palette-secondary95: #e6f2ff; - --md-ref-palette-secondary98: #f7f9ff; - --md-ref-palette-secondary99: #fcfcff; - --md-ref-palette-secondary100: #ffffff; - /* tertiary */ - --md-ref-palette-tertiary0: #000000; - --md-ref-palette-tertiary10: #211634; - --md-ref-palette-tertiary20: #362b4a; - --md-ref-palette-tertiary25: #423656; - --md-ref-palette-tertiary30: #4d4162; - --md-ref-palette-tertiary35: #594c6e; - --md-ref-palette-tertiary40: #66587b; - --md-ref-palette-tertiary50: #7f7195; - --md-ref-palette-tertiary60: #998ab0; - --md-ref-palette-tertiary70: #b4a4cb; - --md-ref-palette-tertiary80: #d0bfe7; - --md-ref-palette-tertiary90: #ecdcff; - --md-ref-palette-tertiary95: #f7edff; - --md-ref-palette-tertiary98: #fef7ff; - --md-ref-palette-tertiary99: #fffbff; - --md-ref-palette-tertiary100: #ffffff; - /* neutral */ - --md-ref-palette-neutral0: #000000; - --md-ref-palette-neutral10: #1a1c1e; - --md-ref-palette-neutral20: #2e3133; - --md-ref-palette-neutral25: #3a3c3e; - --md-ref-palette-neutral30: #454749; - --md-ref-palette-neutral35: #515255; - --md-ref-palette-neutral40: #5d5e61; - --md-ref-palette-neutral50: #76777a; - --md-ref-palette-neutral60: #8f9194; - --md-ref-palette-neutral70: #aaabae; - --md-ref-palette-neutral80: #c6c6c9; - --md-ref-palette-neutral90: #e2e2e5; - --md-ref-palette-neutral95: #f0f0f3; - --md-ref-palette-neutral98: #f9f9fc; - --md-ref-palette-neutral99: #fcfcff; - --md-ref-palette-neutral100: #ffffff; - /* neutral-variant */ - --md-ref-palette-neutral-variant0: #000000; - --md-ref-palette-neutral-variant10: #161c22; - --md-ref-palette-neutral-variant20: #2b3137; - --md-ref-palette-neutral-variant25: #363c42; - --md-ref-palette-neutral-variant30: #41474d; - --md-ref-palette-neutral-variant35: #4d5359; - --md-ref-palette-neutral-variant40: #595f65; - --md-ref-palette-neutral-variant50: #72787e; - --md-ref-palette-neutral-variant60: #8b9198; - --md-ref-palette-neutral-variant70: #a6acb3; - --md-ref-palette-neutral-variant80: #c1c7ce; - --md-ref-palette-neutral-variant90: #dee3ea; - --md-ref-palette-neutral-variant95: #ecf1f9; - --md-ref-palette-neutral-variant98: #f7f9ff; - --md-ref-palette-neutral-variant99: #fcfcff; - --md-ref-palette-neutral-variant100: #ffffff; - /* error */ - --md-ref-palette-error0: #000000; - --md-ref-palette-error10: #410002; - --md-ref-palette-error20: #690005; - --md-ref-palette-error25: #7e0007; - --md-ref-palette-error30: #93000a; - --md-ref-palette-error35: #a80710; - --md-ref-palette-error40: #ba1a1a; - --md-ref-palette-error50: #de3730; - --md-ref-palette-error60: #ff5449; - --md-ref-palette-error70: #ff897d; - --md-ref-palette-error80: #ffb4ab; - --md-ref-palette-error90: #ffdad6; - --md-ref-palette-error95: #ffedea; - --md-ref-palette-error98: #fff8f7; - --md-ref-palette-error99: #fffbff; - --md-ref-palette-error100: #ffffff; - /* light */ - --md-sys-color-primary-light: #006495; - --md-sys-color-on-primary-light: #ffffff; - --md-sys-color-primary-container-light: #cbe6ff; - --md-sys-color-on-primary-container-light: #001e30; - --md-sys-color-secondary-light: #50606f; - --md-sys-color-on-secondary-light: #ffffff; - --md-sys-color-secondary-container-light: #d4e4f6; - --md-sys-color-on-secondary-container-light: #0d1d29; - --md-sys-color-tertiary-light: #66587b; - --md-sys-color-on-tertiary-light: #ffffff; - --md-sys-color-tertiary-container-light: #ecdcff; - --md-sys-color-on-tertiary-container-light: #211634; - --md-sys-color-error-light: #ba1a1a; - --md-sys-color-error-container-light: #ffdad6; - --md-sys-color-on-error-light: #ffffff; - --md-sys-color-on-error-container-light: #410002; - --md-sys-color-background-light: #fcfcff; - --md-sys-color-on-background-light: #1a1c1e; - --md-sys-color-surface-light: #fcfcff; - --md-sys-color-on-surface-light: #1a1c1e; - --md-sys-color-surface-variant-light: #dee3ea; - --md-sys-color-on-surface-variant-light: #41474d; - --md-sys-color-outline-light: #72787e; - --md-sys-color-inverse-on-surface-light: #f0f0f3; - --md-sys-color-inverse-surface-light: #2e3133; - --md-sys-color-inverse-primary-light: #8fcdff; - --md-sys-color-shadow-light: #000000; - --md-sys-color-surface-tint-light: #006495; - --md-sys-color-outline-variant-light: #c1c7ce; - --md-sys-color-scrim-light: #000000; - /* dark */ - --md-sys-color-primary-dark: #8fcdff; - --md-sys-color-on-primary-dark: #003450; - --md-sys-color-primary-container-dark: #004b71; - --md-sys-color-on-primary-container-dark: #cbe6ff; - --md-sys-color-secondary-dark: #b8c8d9; - --md-sys-color-on-secondary-dark: #22323f; - --md-sys-color-secondary-container-dark: #394856; - --md-sys-color-on-secondary-container-dark: #d4e4f6; - --md-sys-color-tertiary-dark: #d0bfe7; - --md-sys-color-on-tertiary-dark: #362b4a; - --md-sys-color-tertiary-container-dark: #4d4162; - --md-sys-color-on-tertiary-container-dark: #ecdcff; - --md-sys-color-error-dark: #ffb4ab; - --md-sys-color-error-container-dark: #93000a; - --md-sys-color-on-error-dark: #690005; - --md-sys-color-on-error-container-dark: #ffdad6; - --md-sys-color-background-dark: #1a1c1e; - --md-sys-color-on-background-dark: #e2e2e5; - --md-sys-color-surface-dark: #1a1c1e; - --md-sys-color-on-surface-dark: #e2e2e5; - --md-sys-color-surface-variant-dark: #41474d; - --md-sys-color-on-surface-variant-dark: #c1c7ce; - --md-sys-color-outline-dark: #8b9198; - --md-sys-color-inverse-on-surface-dark: #1a1c1e; - --md-sys-color-inverse-surface-dark: #e2e2e5; - --md-sys-color-inverse-primary-dark: #006495; - --md-sys-color-shadow-dark: #000000; - --md-sys-color-surface-tint-dark: #8fcdff; - --md-sys-color-outline-variant-dark: #41474d; - --md-sys-color-scrim-dark: #000000; - /* display - large */ - --md-sys-typescale-display-large-font-family-name: Roboto; - --md-sys-typescale-display-large-font-family-style: Regular; - --md-sys-typescale-display-large-font-weight: 400px; - --md-sys-typescale-display-large-font-size: 57px; - --md-sys-typescale-display-large-line-height: 64px; - --md-sys-typescale-display-large-letter-spacing: -0.25px; - /* display - medium */ - --md-sys-typescale-display-medium-font-family-name: Roboto; - --md-sys-typescale-display-medium-font-family-style: Regular; - --md-sys-typescale-display-medium-font-weight: 400px; - --md-sys-typescale-display-medium-font-size: 45px; - --md-sys-typescale-display-medium-line-height: 52px; - --md-sys-typescale-display-medium-letter-spacing: 0px; - /* display - small */ - --md-sys-typescale-display-small-font-family-name: Roboto; - --md-sys-typescale-display-small-font-family-style: Regular; - --md-sys-typescale-display-small-font-weight: 400px; - --md-sys-typescale-display-small-font-size: 36px; - --md-sys-typescale-display-small-line-height: 44px; - --md-sys-typescale-display-small-letter-spacing: 0px; - /* headline - large */ - --md-sys-typescale-headline-large-font-family-name: Roboto; - --md-sys-typescale-headline-large-font-family-style: Regular; - --md-sys-typescale-headline-large-font-weight: 400px; - --md-sys-typescale-headline-large-font-size: 32px; - --md-sys-typescale-headline-large-line-height: 40px; - --md-sys-typescale-headline-large-letter-spacing: 0px; - /* headline - medium */ - --md-sys-typescale-headline-medium-font-family-name: Roboto; - --md-sys-typescale-headline-medium-font-family-style: Regular; - --md-sys-typescale-headline-medium-font-weight: 400px; - --md-sys-typescale-headline-medium-font-size: 28px; - --md-sys-typescale-headline-medium-line-height: 36px; - --md-sys-typescale-headline-medium-letter-spacing: 0px; - /* headline - small */ - --md-sys-typescale-headline-small-font-family-name: Roboto; - --md-sys-typescale-headline-small-font-family-style: Regular; - --md-sys-typescale-headline-small-font-weight: 400px; - --md-sys-typescale-headline-small-font-size: 24px; - --md-sys-typescale-headline-small-line-height: 32px; - --md-sys-typescale-headline-small-letter-spacing: 0px; - /* body - large */ - --md-sys-typescale-body-large-font-family-name: Roboto; - --md-sys-typescale-body-large-font-family-style: Regular; - --md-sys-typescale-body-large-font-weight: 400px; - --md-sys-typescale-body-large-font-size: 16px; - --md-sys-typescale-body-large-line-height: 24px; - --md-sys-typescale-body-large-letter-spacing: 0.50px; - /* body - medium */ - --md-sys-typescale-body-medium-font-family-name: Roboto; - --md-sys-typescale-body-medium-font-family-style: Regular; - --md-sys-typescale-body-medium-font-weight: 400px; - --md-sys-typescale-body-medium-font-size: 14px; - --md-sys-typescale-body-medium-line-height: 20px; - --md-sys-typescale-body-medium-letter-spacing: 0.25px; - /* body - small */ - --md-sys-typescale-body-small-font-family-name: Roboto; - --md-sys-typescale-body-small-font-family-style: Regular; - --md-sys-typescale-body-small-font-weight: 400px; - --md-sys-typescale-body-small-font-size: 12px; - --md-sys-typescale-body-small-line-height: 16px; - --md-sys-typescale-body-small-letter-spacing: 0.40px; - /* label - large */ - --md-sys-typescale-label-large-font-family-name: Roboto; - --md-sys-typescale-label-large-font-family-style: Medium; - --md-sys-typescale-label-large-font-weight: 500px; - --md-sys-typescale-label-large-font-size: 14px; - --md-sys-typescale-label-large-line-height: 20px; - --md-sys-typescale-label-large-letter-spacing: 0.10px; - /* label - medium */ - --md-sys-typescale-label-medium-font-family-name: Roboto; - --md-sys-typescale-label-medium-font-family-style: Medium; - --md-sys-typescale-label-medium-font-weight: 500px; - --md-sys-typescale-label-medium-font-size: 12px; - --md-sys-typescale-label-medium-line-height: 16px; - --md-sys-typescale-label-medium-letter-spacing: 0.50px; - /* label - small */ - --md-sys-typescale-label-small-font-family-name: Roboto; - --md-sys-typescale-label-small-font-family-style: Medium; - --md-sys-typescale-label-small-font-weight: 500px; - --md-sys-typescale-label-small-font-size: 11px; - --md-sys-typescale-label-small-line-height: 16px; - --md-sys-typescale-label-small-letter-spacing: 0.50px; - /* title - large */ - --md-sys-typescale-title-large-font-family-name: Roboto; - --md-sys-typescale-title-large-font-family-style: Regular; - --md-sys-typescale-title-large-font-weight: 400px; - --md-sys-typescale-title-large-font-size: 22px; - --md-sys-typescale-title-large-line-height: 28px; - --md-sys-typescale-title-large-letter-spacing: 0px; - /* title - medium */ - --md-sys-typescale-title-medium-font-family-name: Roboto; - --md-sys-typescale-title-medium-font-family-style: Medium; - --md-sys-typescale-title-medium-font-weight: 500px; - --md-sys-typescale-title-medium-font-size: 16px; - --md-sys-typescale-title-medium-line-height: 24px; - --md-sys-typescale-title-medium-letter-spacing: 0.15px; - /* title - small */ - --md-sys-typescale-title-small-font-family-name: Roboto; - --md-sys-typescale-title-small-font-family-style: Medium; - --md-sys-typescale-title-small-font-weight: 500px; - --md-sys-typescale-title-small-font-size: 14px; - --md-sys-typescale-title-small-line-height: 20px; - --md-sys-typescale-title-small-letter-spacing: 0.10px; -} - -/* System Defaults */ -:root, :host { - color-scheme: light; - --md-sys-color-primary: var(--md-sys-color-primary-light); - --md-sys-color-on-primary: var(--md-sys-color-on-primary-light); - --md-sys-color-primary-container: var(--md-sys-color-primary-container-light); - --md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-light); - --md-sys-color-secondary: var(--md-sys-color-secondary-light); - --md-sys-color-on-secondary: var(--md-sys-color-on-secondary-light); - --md-sys-color-secondary-container: var(--md-sys-color-secondary-container-light); - --md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-light); - --md-sys-color-tertiary: var(--md-sys-color-tertiary-light); - --md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-light); - --md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-light); - --md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-light); - --md-sys-color-error: var(--md-sys-color-error-light); - --md-sys-color-on-error: var(--md-sys-color-on-error-light); - --md-sys-color-error-container: var(--md-sys-color-error-container-light); - --md-sys-color-on-error-container: var(--md-sys-color-on-error-container-light); - --md-sys-color-outline: var(--md-sys-color-outline-light); - --md-sys-color-background: var(--md-sys-color-background-light); - --md-sys-color-on-background: var(--md-sys-color-on-background-light); - --md-sys-color-surface: var(--md-sys-color-surface-light); - --md-sys-color-on-surface: var(--md-sys-color-on-surface-light); - --md-sys-color-surface-variant: var(--md-sys-color-surface-variant-light); - --md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-light); - --md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-light); - --md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-light); - --md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-light); - --md-sys-color-shadow: var(--md-sys-color-shadow-light); - --md-sys-color-surface-tint: var(--md-sys-color-surface-tint-light); - --md-sys-color-outline-variant: var(--md-sys-color-outline-variant-light); - --md-sys-color-scrim: var(--md-sys-color-scrim-light); -} - -@media (prefers-color-scheme: dark) { - :root, :host { - color-scheme: dark; - --md-sys-color-primary: var(--md-sys-color-primary-dark); - --md-sys-color-on-primary: var(--md-sys-color-on-primary-dark); - --md-sys-color-primary-container: var(--md-sys-color-primary-container-dark); - --md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-dark); - --md-sys-color-secondary: var(--md-sys-color-secondary-dark); - --md-sys-color-on-secondary: var(--md-sys-color-on-secondary-dark); - --md-sys-color-secondary-container: var(--md-sys-color-secondary-container-dark); - --md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-dark); - --md-sys-color-tertiary: var(--md-sys-color-tertiary-dark); - --md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-dark); - --md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-dark); - --md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-dark); - --md-sys-color-error: var(--md-sys-color-error-dark); - --md-sys-color-on-error: var(--md-sys-color-on-error-dark); - --md-sys-color-error-container: var(--md-sys-color-error-container-dark); - --md-sys-color-on-error-container: var(--md-sys-color-on-error-container-dark); - --md-sys-color-outline: var(--md-sys-color-outline-dark); - --md-sys-color-background: var(--md-sys-color-background-dark); - --md-sys-color-on-background: var(--md-sys-color-on-background-dark); - --md-sys-color-surface: var(--md-sys-color-surface-dark); - --md-sys-color-on-surface: var(--md-sys-color-on-surface-dark); - --md-sys-color-surface-variant: var(--md-sys-color-surface-variant-dark); - --md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-dark); - --md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-dark); - --md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-dark); - --md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-dark); - --md-sys-color-shadow: var(--md-sys-color-shadow-dark); - --md-sys-color-surface-tint: var(--md-sys-color-surface-tint-dark); - --md-sys-color-outline-variant: var(--md-sys-color-outline-variant-dark); - --md-sys-color-scrim: var(--md-sys-color-scrim-dark); - } -} -/* ===================================================================== Themes */ -:root[theme=light] { - color-scheme: light; - --md-sys-color-primary: var(--md-sys-color-primary-light); - --md-sys-color-on-primary: var(--md-sys-color-on-primary-light); - --md-sys-color-primary-container: var(--md-sys-color-primary-container-light); - --md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-light); - --md-sys-color-secondary: var(--md-sys-color-secondary-light); - --md-sys-color-on-secondary: var(--md-sys-color-on-secondary-light); - --md-sys-color-secondary-container: var(--md-sys-color-secondary-container-light); - --md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-light); - --md-sys-color-tertiary: var(--md-sys-color-tertiary-light); - --md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-light); - --md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-light); - --md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-light); - --md-sys-color-error: var(--md-sys-color-error-light); - --md-sys-color-on-error: var(--md-sys-color-on-error-light); - --md-sys-color-error-container: var(--md-sys-color-error-container-light); - --md-sys-color-on-error-container: var(--md-sys-color-on-error-container-light); - --md-sys-color-outline: var(--md-sys-color-outline-light); - --md-sys-color-background: var(--md-sys-color-background-light); - --md-sys-color-on-background: var(--md-sys-color-on-background-light); - --md-sys-color-surface: var(--md-sys-color-surface-light); - --md-sys-color-on-surface: var(--md-sys-color-on-surface-light); - --md-sys-color-surface-variant: var(--md-sys-color-surface-variant-light); - --md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-light); - --md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-light); - --md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-light); - --md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-light); - --md-sys-color-shadow: var(--md-sys-color-shadow-light); - --md-sys-color-surface-tint: var(--md-sys-color-surface-tint-light); - --md-sys-color-outline-variant: var(--md-sys-color-outline-variant-light); - --md-sys-color-scrim: var(--md-sys-color-scrim-light); -} - -:root[theme=dark] { - color-scheme: dark; - --md-sys-color-primary: var(--md-sys-color-primary-dark); - --md-sys-color-on-primary: var(--md-sys-color-on-primary-dark); - --md-sys-color-primary-container: var(--md-sys-color-primary-container-dark); - --md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-dark); - --md-sys-color-secondary: var(--md-sys-color-secondary-dark); - --md-sys-color-on-secondary: var(--md-sys-color-on-secondary-dark); - --md-sys-color-secondary-container: var(--md-sys-color-secondary-container-dark); - --md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-dark); - --md-sys-color-tertiary: var(--md-sys-color-tertiary-dark); - --md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-dark); - --md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-dark); - --md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-dark); - --md-sys-color-error: var(--md-sys-color-error-dark); - --md-sys-color-on-error: var(--md-sys-color-on-error-dark); - --md-sys-color-error-container: var(--md-sys-color-error-container-dark); - --md-sys-color-on-error-container: var(--md-sys-color-on-error-container-dark); - --md-sys-color-outline: var(--md-sys-color-outline-dark); - --md-sys-color-background: var(--md-sys-color-background-dark); - --md-sys-color-on-background: var(--md-sys-color-on-background-dark); - --md-sys-color-surface: var(--md-sys-color-surface-dark); - --md-sys-color-on-surface: var(--md-sys-color-on-surface-dark); - --md-sys-color-surface-variant: var(--md-sys-color-surface-variant-dark); - --md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-dark); - --md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-dark); - --md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-dark); - --md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-dark); - --md-sys-color-shadow: var(--md-sys-color-shadow-dark); - --md-sys-color-surface-tint: var(--md-sys-color-surface-tint-dark); - --md-sys-color-outline-variant: var(--md-sys-color-outline-variant-dark); - --md-sys-color-scrim: var(--md-sys-color-scrim-dark); -} - -.display-large { - font-family: var(--md-sys-typescale-display-large-font-family-name); - font-style: var(--md-sys-typescale-display-large-font-family-style); - font-weight: var(--md-sys-typescale-display-large-font-weight); - font-size: var(--md-sys-typescale-display-large-font-size); - letter-spacing: var(--md-sys-typescale-display-large-tracking); - line-height: var(--md-sys-typescale-display-large-height); - text-transform: var(--md-sys-typescale-display-large-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-display-large-text-decoration); - text-decoration: var(--md-sys-typescale-display-large-text-decoration); -} - -.display-medium { - font-family: var(--md-sys-typescale-display-medium-font-family-name); - font-style: var(--md-sys-typescale-display-medium-font-family-style); - font-weight: var(--md-sys-typescale-display-medium-font-weight); - font-size: var(--md-sys-typescale-display-medium-font-size); - letter-spacing: var(--md-sys-typescale-display-medium-tracking); - line-height: var(--md-sys-typescale-display-medium-height); - text-transform: var(--md-sys-typescale-display-medium-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-display-medium-text-decoration); - text-decoration: var(--md-sys-typescale-display-medium-text-decoration); -} - -.display-small { - font-family: var(--md-sys-typescale-display-small-font-family-name); - font-style: var(--md-sys-typescale-display-small-font-family-style); - font-weight: var(--md-sys-typescale-display-small-font-weight); - font-size: var(--md-sys-typescale-display-small-font-size); - letter-spacing: var(--md-sys-typescale-display-small-tracking); - line-height: var(--md-sys-typescale-display-small-height); - text-transform: var(--md-sys-typescale-display-small-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-display-small-text-decoration); - text-decoration: var(--md-sys-typescale-display-small-text-decoration); -} - -.headline-large { - font-family: var(--md-sys-typescale-headline-large-font-family-name); - font-style: var(--md-sys-typescale-headline-large-font-family-style); - font-weight: var(--md-sys-typescale-headline-large-font-weight); - font-size: var(--md-sys-typescale-headline-large-font-size); - letter-spacing: var(--md-sys-typescale-headline-large-tracking); - line-height: var(--md-sys-typescale-headline-large-height); - text-transform: var(--md-sys-typescale-headline-large-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-headline-large-text-decoration); - text-decoration: var(--md-sys-typescale-headline-large-text-decoration); -} - -.headline-medium { - font-family: var(--md-sys-typescale-headline-medium-font-family-name); - font-style: var(--md-sys-typescale-headline-medium-font-family-style); - font-weight: var(--md-sys-typescale-headline-medium-font-weight); - font-size: var(--md-sys-typescale-headline-medium-font-size); - letter-spacing: var(--md-sys-typescale-headline-medium-tracking); - line-height: var(--md-sys-typescale-headline-medium-height); - text-transform: var(--md-sys-typescale-headline-medium-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-headline-medium-text-decoration); - text-decoration: var(--md-sys-typescale-headline-medium-text-decoration); -} - -.headline-small { - font-family: var(--md-sys-typescale-headline-small-font-family-name); - font-style: var(--md-sys-typescale-headline-small-font-family-style); - font-weight: var(--md-sys-typescale-headline-small-font-weight); - font-size: var(--md-sys-typescale-headline-small-font-size); - letter-spacing: var(--md-sys-typescale-headline-small-tracking); - line-height: var(--md-sys-typescale-headline-small-height); - text-transform: var(--md-sys-typescale-headline-small-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-headline-small-text-decoration); - text-decoration: var(--md-sys-typescale-headline-small-text-decoration); -} - -.body-large { - font-family: var(--md-sys-typescale-body-large-font-family-name); - font-style: var(--md-sys-typescale-body-large-font-family-style); - font-weight: var(--md-sys-typescale-body-large-font-weight); - font-size: var(--md-sys-typescale-body-large-font-size); - letter-spacing: var(--md-sys-typescale-body-large-tracking); - line-height: var(--md-sys-typescale-body-large-height); - text-transform: var(--md-sys-typescale-body-large-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-body-large-text-decoration); - text-decoration: var(--md-sys-typescale-body-large-text-decoration); -} - -.body-medium { - font-family: var(--md-sys-typescale-body-medium-font-family-name); - font-style: var(--md-sys-typescale-body-medium-font-family-style); - font-weight: var(--md-sys-typescale-body-medium-font-weight); - font-size: var(--md-sys-typescale-body-medium-font-size); - letter-spacing: var(--md-sys-typescale-body-medium-tracking); - line-height: var(--md-sys-typescale-body-medium-height); - text-transform: var(--md-sys-typescale-body-medium-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-body-medium-text-decoration); - text-decoration: var(--md-sys-typescale-body-medium-text-decoration); -} - -.body-small { - font-family: var(--md-sys-typescale-body-small-font-family-name); - font-style: var(--md-sys-typescale-body-small-font-family-style); - font-weight: var(--md-sys-typescale-body-small-font-weight); - font-size: var(--md-sys-typescale-body-small-font-size); - letter-spacing: var(--md-sys-typescale-body-small-tracking); - line-height: var(--md-sys-typescale-body-small-height); - text-transform: var(--md-sys-typescale-body-small-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-body-small-text-decoration); - text-decoration: var(--md-sys-typescale-body-small-text-decoration); -} - -.label-large { - font-family: var(--md-sys-typescale-label-large-font-family-name); - font-style: var(--md-sys-typescale-label-large-font-family-style); - font-weight: var(--md-sys-typescale-label-large-font-weight); - font-size: var(--md-sys-typescale-label-large-font-size); - letter-spacing: var(--md-sys-typescale-label-large-tracking); - line-height: var(--md-sys-typescale-label-large-height); - text-transform: var(--md-sys-typescale-label-large-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-label-large-text-decoration); - text-decoration: var(--md-sys-typescale-label-large-text-decoration); -} - -.label-medium { - font-family: var(--md-sys-typescale-label-medium-font-family-name); - font-style: var(--md-sys-typescale-label-medium-font-family-style); - font-weight: var(--md-sys-typescale-label-medium-font-weight); - font-size: var(--md-sys-typescale-label-medium-font-size); - letter-spacing: var(--md-sys-typescale-label-medium-tracking); - line-height: var(--md-sys-typescale-label-medium-height); - text-transform: var(--md-sys-typescale-label-medium-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-label-medium-text-decoration); - text-decoration: var(--md-sys-typescale-label-medium-text-decoration); -} - -.label-small { - font-family: var(--md-sys-typescale-label-small-font-family-name); - font-style: var(--md-sys-typescale-label-small-font-family-style); - font-weight: var(--md-sys-typescale-label-small-font-weight); - font-size: var(--md-sys-typescale-label-small-font-size); - letter-spacing: var(--md-sys-typescale-label-small-tracking); - line-height: var(--md-sys-typescale-label-small-height); - text-transform: var(--md-sys-typescale-label-small-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-label-small-text-decoration); - text-decoration: var(--md-sys-typescale-label-small-text-decoration); -} - -.title-large { - font-family: var(--md-sys-typescale-title-large-font-family-name); - font-style: var(--md-sys-typescale-title-large-font-family-style); - font-weight: var(--md-sys-typescale-title-large-font-weight); - font-size: var(--md-sys-typescale-title-large-font-size); - letter-spacing: var(--md-sys-typescale-title-large-tracking); - line-height: var(--md-sys-typescale-title-large-height); - text-transform: var(--md-sys-typescale-title-large-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-title-large-text-decoration); - text-decoration: var(--md-sys-typescale-title-large-text-decoration); -} - -.title-medium { - font-family: var(--md-sys-typescale-title-medium-font-family-name); - font-style: var(--md-sys-typescale-title-medium-font-family-style); - font-weight: var(--md-sys-typescale-title-medium-font-weight); - font-size: var(--md-sys-typescale-title-medium-font-size); - letter-spacing: var(--md-sys-typescale-title-medium-tracking); - line-height: var(--md-sys-typescale-title-medium-height); - text-transform: var(--md-sys-typescale-title-medium-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-title-medium-text-decoration); - text-decoration: var(--md-sys-typescale-title-medium-text-decoration); -} - -.title-small { - font-family: var(--md-sys-typescale-title-small-font-family-name); - font-style: var(--md-sys-typescale-title-small-font-family-style); - font-weight: var(--md-sys-typescale-title-small-font-weight); - font-size: var(--md-sys-typescale-title-small-font-size); - letter-spacing: var(--md-sys-typescale-title-small-tracking); - line-height: var(--md-sys-typescale-title-small-height); - text-transform: var(--md-sys-typescale-title-small-text-transform); - -webkit-text-decoration: var(--md-sys-typescale-title-small-text-decoration); - text-decoration: var(--md-sys-typescale-title-small-text-decoration); -} - -.primary { - background-color: var(--md-sys-color-primary); -} - -.primary-text { - color: var(--md-sys-color-primary); -} - -.on-primary { - background-color: var(--md-sys-color-on-primary); -} - -.on-primary-text { - color: var(--md-sys-color-on-primary); -} - -.primary-container { - background-color: var(--md-sys-color-primary-container); -} - -.primary-container-text { - color: var(--md-sys-color-primary-container); -} - -.on-primary-container { - background-color: var(--md-sys-color-on-primary-container); -} - -.on-primary-container-text { - color: var(--md-sys-color-on-primary-container); -} - -.secondary { - background-color: var(--md-sys-color-secondary); -} - -.secondary-text { - color: var(--md-sys-color-secondary); -} - -.on-secondary { - background-color: var(--md-sys-color-on-secondary); -} - -.on-secondary-text { - color: var(--md-sys-color-on-secondary); -} - -.secondary-container { - background-color: var(--md-sys-color-secondary-container); -} - -.secondary-container-text { - color: var(--md-sys-color-secondary-container); -} - -.on-secondary-container { - background-color: var(--md-sys-color-on-secondary-container); -} - -.on-secondary-container-text { - color: var(--md-sys-color-on-secondary-container); -} - -.tertiary { - background-color: var(--md-sys-color-tertiary); -} - -.tertiary-text { - color: var(--md-sys-color-tertiary); -} - -.on-tertiary { - background-color: var(--md-sys-color-on-tertiary); -} - -.on-tertiary-text { - color: var(--md-sys-color-on-tertiary); -} - -.tertiary-container { - background-color: var(--md-sys-color-tertiary-container); -} - -.tertiary-container-text { - color: var(--md-sys-color-tertiary-container); -} - -.on-tertiary-container { - background-color: var(--md-sys-color-on-tertiary-container); -} - -.on-tertiary-container-text { - color: var(--md-sys-color-on-tertiary-container); -} - -.error { - background-color: var(--md-sys-color-error); -} - -.error-text { - color: var(--md-sys-color-error); -} - -.on-error { - background-color: var(--md-sys-color-on-error); -} - -.on-error-text { - color: var(--md-sys-color-on-error); -} - -.error-container { - background-color: var(--md-sys-color-error-container); -} - -.error-container-text { - color: var(--md-sys-color-error-container); -} - -.on-error-container { - background-color: var(--md-sys-color-on-error-container); -} - -.on-error-container-text { - color: var(--md-sys-color-on-error-container); -} - -.background { - background-color: var(--md-sys-color-background); -} - -.background-text { - color: var(--md-sys-color-background); -} - -.on-background { - background-color: var(--md-sys-color-on-background); -} - -.on-background-text { - color: var(--md-sys-color-on-background); -} - -.surface { - background-color: var(--md-sys-color-surface); -} - -.surface-text { - color: var(--md-sys-color-surface); -} - -.on-surface { - background-color: var(--md-sys-color-on-surface); -} - -.on-surface-text { - color: var(--md-sys-color-on-surface); -} - -.surface-variant { - background-color: var(--md-sys-color-surface-variant); -} - -.surface-variant-text { - color: var(--md-sys-color-surface-variant); -} - -.on-surface-variant { - background-color: var(--md-sys-color-on-surface-variant); -} - -.on-surface-variant-text { - color: var(--md-sys-color-on-surface-variant); -} - -.outline { - background-color: var(--md-sys-color-outline); -} - -.outline-text { - color: var(--md-sys-color-outline); -} - -.inverse-on-surface { - background-color: var(--md-sys-color-inverse-on-surface); -} - -.inverse-on-surface-text { - color: var(--md-sys-color-inverse-on-surface); -} - -.inverse-surface { - background-color: var(--md-sys-color-inverse-surface); -} - -.inverse-surface-text { - color: var(--md-sys-color-inverse-surface); -} - -.inverse-primary { - background-color: var(--md-sys-color-inverse-primary); -} - -.inverse-primary-text { - color: var(--md-sys-color-inverse-primary); -} - -.shadow { - background-color: var(--md-sys-color-shadow); -} - -.shadow-text { - color: var(--md-sys-color-shadow); -} - -.surface-tint { - background-color: var(--md-sys-color-surface-tint); -} - -.surface-tint-text { - color: var(--md-sys-color-surface-tint); -} - -.outline-variant { - background-color: var(--md-sys-color-outline-variant); -} - -.outline-variant-text { - color: var(--md-sys-color-outline-variant); -} - -.scrim { - background-color: var(--md-sys-color-scrim); -} - -.scrim-text { - color: var(--md-sys-color-scrim); -} - -a { - text-decoration: none; -} - -html { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; - font-weight: normal; - color: var(--md-sys-color-on-background); -} -@media only screen and (min-width: 0) { - html { - font-size: 14px; - } -} -@media only screen and (min-width: 993px) { - html { - font-size: 14.5px; - } -} -@media only screen and (min-width: 1201px) { - html { - font-size: 15px; - } -} - -h1, h2, h3, h4, h5, h6 { - font-weight: 400; - line-height: 1.3; -} - -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { - font-weight: inherit; -} - -h1 { - font-size: 4.2rem; - line-height: 110%; - margin: 2.8rem 0 1.68rem 0; -} - -h2 { - font-size: 3.56rem; - line-height: 110%; - margin: 2.3733333333rem 0 1.424rem 0; -} - -h3 { - font-size: 2.92rem; - line-height: 110%; - margin: 1.9466666667rem 0 1.168rem 0; -} - -h4 { - font-size: 2.28rem; - line-height: 110%; - margin: 1.52rem 0 0.912rem 0; -} - -h5 { - font-size: 1.64rem; - line-height: 110%; - margin: 1.0933333333rem 0 0.656rem 0; -} - -h6 { - font-size: 1.15rem; - line-height: 110%; - margin: 0.7666666667rem 0 0.46rem 0; -} - -em { - font-style: italic; -} - -strong { - font-weight: 500; -} - -small { - font-size: 75%; -} - -.light { - font-weight: 300; -} - -.thin { - font-weight: 200; -} - -@media only screen and (min-width: 360px) { - .flow-text { - font-size: 1.2rem; - } -} -@media only screen and (min-width: 390px) { - .flow-text { - font-size: 1.224rem; - } -} -@media only screen and (min-width: 420px) { - .flow-text { - font-size: 1.248rem; - } -} -@media only screen and (min-width: 450px) { - .flow-text { - font-size: 1.272rem; - } -} -@media only screen and (min-width: 480px) { - .flow-text { - font-size: 1.296rem; - } -} -@media only screen and (min-width: 510px) { - .flow-text { - font-size: 1.32rem; - } -} -@media only screen and (min-width: 540px) { - .flow-text { - font-size: 1.344rem; - } -} -@media only screen and (min-width: 570px) { - .flow-text { - font-size: 1.368rem; - } -} -@media only screen and (min-width: 600px) { - .flow-text { - font-size: 1.392rem; - } -} -@media only screen and (min-width: 630px) { - .flow-text { - font-size: 1.416rem; - } -} -@media only screen and (min-width: 660px) { - .flow-text { - font-size: 1.44rem; - } -} -@media only screen and (min-width: 690px) { - .flow-text { - font-size: 1.464rem; - } -} -@media only screen and (min-width: 720px) { - .flow-text { - font-size: 1.488rem; - } -} -@media only screen and (min-width: 750px) { - .flow-text { - font-size: 1.512rem; - } -} -@media only screen and (min-width: 780px) { - .flow-text { - font-size: 1.536rem; - } -} -@media only screen and (min-width: 810px) { - .flow-text { - font-size: 1.56rem; - } -} -@media only screen and (min-width: 840px) { - .flow-text { - font-size: 1.584rem; - } -} -@media only screen and (min-width: 870px) { - .flow-text { - font-size: 1.608rem; - } -} -@media only screen and (min-width: 900px) { - .flow-text { - font-size: 1.632rem; - } -} -@media only screen and (min-width: 930px) { - .flow-text { - font-size: 1.656rem; - } -} -@media only screen and (min-width: 960px) { - .flow-text { - font-size: 1.68rem; - } -} -@media only screen and (max-width: 360px) { - .flow-text { - font-size: 1.2rem; - } -} - -html { - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -*, *:before, *:after { - -webkit-box-sizing: inherit; - box-sizing: inherit; -} - -body { - background-color: var(--md-sys-color-background); - color: var(--md-sys-color-on-background); -} - -button, -input, -optgroup, -select, -textarea { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; -} - -a { - color: colorFunc("light-blue", "darken-1"); - text-decoration: none; - -webkit-tap-highlight-color: transparent; -} - -.valign-wrapper { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; -} - -.clearfix { - clear: both; -} - -.z-depth-0, .pagination li.active a:focus, .pagination li.disabled a, .btn.filled:focus, .btn.tonal:focus, .btn.text, .btn-flat, .btn.disabled, .btn-floating.disabled, .btn-large.disabled, .btn-small.disabled, .btn-flat.disabled, -.btn:disabled, .btn-floating:disabled, .btn-large:disabled, .btn-small:disabled, .btn-flat:disabled, -.btn[disabled], .btn-floating[disabled], .btn-large[disabled], .btn-small[disabled], .btn-flat[disabled], .filled.btn-floating:focus, .tonal.btn-floating:focus, .text.btn-floating, .filled.btn-large:focus, .tonal.btn-large:focus, .text.btn-large, .filled.btn-small:focus, .tonal.btn-small:focus, .text.btn-small { - -webkit-box-shadow: none !important; - box-shadow: none !important; -} - -/* 2dp elevation modified*/ -.z-depth-1, .sidenav, .dropdown-content, .collapsible, .pagination li.active a:hover, .card-panel, .card, .btn.filled:hover, .btn.tonal:hover, .btn.elevated, .btn.elevated:focus, .filled.btn-floating:hover, .tonal.btn-floating:hover, .elevated.btn-floating, .elevated.btn-floating:focus, .btn-floating, .filled.btn-large:hover, .tonal.btn-large:hover, .elevated.btn-large, .elevated.btn-large:focus, .filled.btn-small:hover, .tonal.btn-small:hover, .elevated.btn-small, .elevated.btn-small:focus { - -webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2); -} - -.z-depth-1-half, .btn-floating:hover, .btn-floating:focus { - -webkit-box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14), 0 1px 7px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -1px rgba(0, 0, 0, 0.2); - box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14), 0 1px 7px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -1px rgba(0, 0, 0, 0.2); -} - -/* 6dp elevation modified*/ -.z-depth-2, .btn.elevated:hover, .elevated.btn-floating:hover, .elevated.btn-large:hover, .elevated.btn-small:hover { - -webkit-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3); - box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3); -} - -/* 12dp elevation modified*/ -.z-depth-3, .toast { - -webkit-box-shadow: 0 8px 17px 2px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); - box-shadow: 0 8px 17px 2px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); -} - -/* 16dp elevation */ -.z-depth-4 { - -webkit-box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -7px rgba(0, 0, 0, 0.2); - box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -7px rgba(0, 0, 0, 0.2); -} - -/* 24dp elevation */ -.z-depth-5, .modal { - -webkit-box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12), 0 11px 15px -7px rgba(0, 0, 0, 0.2); - box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12), 0 11px 15px -7px rgba(0, 0, 0, 0.2); -} - -.hoverable { - -webkit-transition: -webkit-box-shadow 0.25s; - transition: -webkit-box-shadow 0.25s; - transition: box-shadow 0.25s; - transition: box-shadow 0.25s, -webkit-box-shadow 0.25s; -} -.hoverable:hover { - -webkit-box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); - box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); -} - -.divider { - height: 1px; - overflow: hidden; - background-color: var(--md-sys-color-outline-variant); -} - -blockquote { - margin: 20px 0; - padding-left: 1.5rem; - border-left: 5px solid var(--md-sys-color-primary); -} - -i { - line-height: inherit; -} -i.left { - float: left; - margin-left: -8px; -} -i.right { - float: right; -} -i.tiny { - font-size: 1rem; -} -i.small { - font-size: 2rem; -} -i.medium { - font-size: 4rem; -} -i.large { - font-size: 6rem; -} - -html.noscroll { - position: fixed; - overflow-y: scroll; - width: 100%; -} - -img.responsive-img, -video.responsive-video { - max-width: 100%; - height: auto; -} - -.parallax-container { - position: relative; - overflow: hidden; - height: 500px; -} -.parallax-container .parallax { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: -1; -} -.parallax-container .parallax img { - opacity: 0; - position: absolute; - left: 50%; - bottom: 0; - min-width: 100%; - min-height: 100%; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - -webkit-transform: translateX(-50%); - transform: translateX(-50%); -} - -.pin-top, .pin-bottom { - position: relative; -} - -.pinned { - position: fixed !important; -} - -select:focus { - outline: 1px solid var(--md-ref-palette-primary80); -} - -label { - font-size: 0.8rem; - color: var(--md-sys-color-on-surface-variant); -} - -/********************* - Transition Classes -**********************/ -ul.staggered-list li { - opacity: 0; -} - -.fade-in { - opacity: 0; - -webkit-transform-origin: 0 50%; - transform-origin: 0 50%; -} - -/********************* - Media Query Classes -**********************/ -@media only screen and (max-width : 600.99px) { - .hide-on-small-only, .hide-on-small-and-down { - display: none !important; - } -} - -@media only screen and (max-width : 992.99px) { - .hide-on-med-and-down { - display: none !important; - } -} - -@media only screen and (min-width : 601px) { - .hide-on-med-and-up { - display: none !important; - } -} - -@media only screen and (min-width: 601px) and (max-width: 992.99px) { - .hide-on-med-only { - display: none !important; - } -} - -@media only screen and (min-width : 993px) { - .hide-on-large-only { - display: none !important; - } -} - -@media only screen and (min-width : 1201px) { - .hide-on-extra-large-only { - display: none !important; - } -} - -@media only screen and (min-width : 1201px) { - .show-on-extra-large { - display: block !important; - } -} - -@media only screen and (min-width : 993px) { - .show-on-large { - display: block !important; - } -} - -@media only screen and (min-width: 601px) and (max-width: 992.99px) { - .show-on-medium { - display: block !important; - } -} - -@media only screen and (max-width : 600.99px) { - .show-on-small { - display: block !important; - } -} - -@media only screen and (min-width : 601px) { - .show-on-medium-and-up { - display: block !important; - } -} - -@media only screen and (max-width : 992.99px) { - .show-on-medium-and-down { - display: block !important; - } -} - -@media only screen and (max-width : 600.99px) { - .center-on-small-only { - text-align: center; - } -} - -.page-footer { - margin-top: 5rem; - padding-top: 3rem; - border-top: 1px dashed var(--md-sys-color-outline-variant); -} -.page-footer p { - color: var(--md-sys-color-outline-light); -} -.page-footer a { - color: var(--md-sys-color-primary); -} -.page-footer .footer-copyright, -.page-footer .footer-copyright a { - overflow: hidden; - min-height: 50px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 10px 0px; -} - -.page-footer ul { - padding-left: 0; - list-style-type: none; -} - -table, th, td { - border: none; -} - -table { - width: 100%; - display: table; - border-collapse: collapse; - border-spacing: 0; -} -table.striped tr { - border-bottom: none; -} -table.striped tbody > tr:nth-child(odd) { - background-color: rgba(0, 0, 0, 0.08); -} -table.highlight > tbody > tr { - -webkit-transition: background-color 0.25s ease; - transition: background-color 0.25s ease; -} -table.highlight > tbody > tr:hover { - background-color: rgba(0, 0, 0, 0.04); -} -table thead { - color: var(--md-sys-color-on-surface-variant); -} -table.centered thead tr th, table.centered tbody tr td { - text-align: center; -} - -tr { - border-bottom: 1px solid var(--md-sys-color-outline-variant); -} - -td, th { - padding: 15px 5px; - display: table-cell; - text-align: left; - vertical-align: middle; - border-radius: 0; -} - -@media only screen and (max-width : 992.99px) { - table.responsive-table { - width: 100%; - border-collapse: collapse; - border-spacing: 0; - display: block; - position: relative; - } - table.responsive-table td:empty:before { - content: " "; - } - table.responsive-table th, - table.responsive-table td { - margin: 0; - vertical-align: top; - } - table.responsive-table th { - text-align: left; - } - table.responsive-table thead { - display: block; - float: left; - } - table.responsive-table thead tr { - display: block; - padding: 0 10px 0 0; - } - table.responsive-table thead tr th::before { - content: " "; - } - table.responsive-table tbody { - display: block; - width: auto; - position: relative; - overflow-x: auto; - white-space: nowrap; - } - table.responsive-table tbody tr { - display: inline-block; - vertical-align: top; - } - table.responsive-table th { - display: block; - text-align: right; - } - table.responsive-table td { - display: block; - min-height: 1.25em; - text-align: left; - } - table.responsive-table tr { - border-bottom: none; - padding: 0 10px; - } - table.responsive-table { - /* sort out borders */ - } - table.responsive-table thead { - border: 0; - border-right: 1px solid var(--md-sys-color-outline-variant); - } -} -.video-container { - position: relative; - padding-bottom: 56.25%; - height: 0; - overflow: hidden; -} -.video-container iframe, .video-container object, .video-container embed { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} - -/******************* - Utility Classes -*******************/ -.hide { - display: none !important; -} - -.left-align { - text-align: left; -} - -.right-align { - text-align: right; -} - -.center, .center-align { - text-align: center; -} - -.left { - float: left !important; -} - -.right { - float: right !important; -} - -.no-select, input[type=range], -input[type=range] + .thumb { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.circle { - border-radius: 50%; -} - -.center-block { - display: block; - margin-left: auto; - margin-right: auto; -} - -.truncate { - display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.no-padding { - padding: 0 !important; -} - -/************************** - Utility Spacing Classes -**************************/ -.m-0 { - margin: 0 !important; -} - -.mt-0 { - margin-top: 0 !important; -} - -.mr-0 { - margin-right: 0 !important; -} - -.mb-0 { - margin-bottom: 0 !important; -} - -.ml-0 { - margin-left: 0 !important; -} - -.mx-0 { - margin-left: 0 !important; - margin-right: 0 !important; -} - -.my-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -.m-1 { - margin: 0.25rem !important; -} - -.mt-1 { - margin-top: 0.25rem !important; -} - -.mr-1 { - margin-right: 0.25rem !important; -} - -.mb-1 { - margin-bottom: 0.25rem !important; -} - -.ml-1 { - margin-left: 0.25rem !important; -} - -.mx-1 { - margin-left: 0.25rem !important; - margin-right: 0.25rem !important; -} - -.my-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; -} - -.m-2 { - margin: 0.5rem !important; -} - -.mt-2 { - margin-top: 0.5rem !important; -} - -.mr-2 { - margin-right: 0.5rem !important; -} - -.mb-2 { - margin-bottom: 0.5rem !important; -} - -.ml-2 { - margin-left: 0.5rem !important; -} - -.mx-2 { - margin-left: 0.5rem !important; - margin-right: 0.5rem !important; -} - -.my-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; -} - -.m-3 { - margin: 0.75rem !important; -} - -.mt-3 { - margin-top: 0.75rem !important; -} - -.mr-3 { - margin-right: 0.75rem !important; -} - -.mb-3 { - margin-bottom: 0.75rem !important; -} - -.ml-3 { - margin-left: 0.75rem !important; -} - -.mx-3 { - margin-left: 0.75rem !important; - margin-right: 0.75rem !important; -} - -.my-3 { - margin-top: 0.75rem !important; - margin-bottom: 0.75rem !important; -} - -.m-4 { - margin: 1rem !important; -} - -.mt-4 { - margin-top: 1rem !important; -} - -.mr-4 { - margin-right: 1rem !important; -} - -.mb-4 { - margin-bottom: 1rem !important; -} - -.ml-4 { - margin-left: 1rem !important; -} - -.mx-4 { - margin-left: 1rem !important; - margin-right: 1rem !important; -} - -.my-4 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; -} - -.m-5 { - margin: 1.5rem !important; -} - -.mt-5 { - margin-top: 1.5rem !important; -} - -.mr-5 { - margin-right: 1.5rem !important; -} - -.mb-5 { - margin-bottom: 1.5rem !important; -} - -.ml-5 { - margin-left: 1.5rem !important; -} - -.mx-5 { - margin-left: 1.5rem !important; - margin-right: 1.5rem !important; -} - -.my-5 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; -} - -.m-6 { - margin: 3rem !important; -} - -.mt-6 { - margin-top: 3rem !important; -} - -.mr-6 { - margin-right: 3rem !important; -} - -.mb-6 { - margin-bottom: 3rem !important; -} - -.ml-6 { - margin-left: 3rem !important; -} - -.mx-6 { - margin-left: 3rem !important; - margin-right: 3rem !important; -} - -.my-6 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; -} - -.m-auto { - margin: auto !important; -} - -.mt-auto { - margin-top: auto !important; -} - -.mr-auto { - margin-right: auto !important; -} - -.mb-auto { - margin-bottom: auto !important; -} - -.ml-auto { - margin-left: auto !important; -} - -.mx-auto { - margin-left: auto !important; - margin-right: auto !important; -} - -.my-auto { - margin-top: auto !important; - margin-bottom: auto !important; -} - -.p-0 { - padding: 0 !important; -} - -.pt-0 { - padding-top: 0 !important; -} - -.pr-0 { - padding-right: 0 !important; -} - -.pb-0 { - padding-bottom: 0 !important; -} - -.pl-0 { - padding-left: 0 !important; -} - -.px-0 { - padding-left: 0 !important; - padding-right: 0 !important; -} - -.py-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; -} - -.p-1 { - padding: 0.25rem !important; -} - -.pt-1 { - padding-top: 0.25rem !important; -} - -.pr-1 { - padding-right: 0.25rem !important; -} - -.pb-1 { - padding-bottom: 0.25rem !important; -} - -.pl-1 { - padding-left: 0.25rem !important; -} - -.px-1 { - padding-left: 0.25rem !important; - padding-right: 0.25rem !important; -} - -.py-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; -} - -.p-2 { - padding: 0.5rem !important; -} - -.pt-2 { - padding-top: 0.5rem !important; -} - -.pr-2 { - padding-right: 0.5rem !important; -} - -.pb-2 { - padding-bottom: 0.5rem !important; -} - -.pl-2 { - padding-left: 0.5rem !important; -} - -.px-2 { - padding-left: 0.5rem !important; - padding-right: 0.5rem !important; -} - -.py-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; -} - -.p-3 { - padding: 0.75rem !important; -} - -.pt-3 { - padding-top: 0.75rem !important; -} - -.pr-3 { - padding-right: 0.75rem !important; -} - -.pb-3 { - padding-bottom: 0.75rem !important; -} - -.pl-3 { - padding-left: 0.75rem !important; -} - -.px-3 { - padding-left: 0.75rem !important; - padding-right: 0.75rem !important; -} - -.py-3 { - padding-top: 0.75rem !important; - padding-bottom: 0.75rem !important; -} - -.p-4 { - padding: 1rem !important; -} - -.pt-4 { - padding-top: 1rem !important; -} - -.pr-4 { - padding-right: 1rem !important; -} - -.pb-4 { - padding-bottom: 1rem !important; -} - -.pl-4 { - padding-left: 1rem !important; -} - -.px-4 { - padding-left: 1rem !important; - padding-right: 1rem !important; -} - -.py-4 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; -} - -.p-5 { - padding: 1.5rem !important; -} - -.pt-5 { - padding-top: 1.5rem !important; -} - -.pr-5 { - padding-right: 1.5rem !important; -} - -.pb-5 { - padding-bottom: 1.5rem !important; -} - -.pl-5 { - padding-left: 1.5rem !important; -} - -.px-5 { - padding-left: 1.5rem !important; - padding-right: 1.5rem !important; -} - -.py-5 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; -} - -.p-6 { - padding: 3rem !important; -} - -.pt-6 { - padding-top: 3rem !important; -} - -.pr-6 { - padding-right: 3rem !important; -} - -.pb-6 { - padding-bottom: 3rem !important; -} - -.pl-6 { - padding-left: 3rem !important; -} - -.px-6 { - padding-left: 3rem !important; - padding-right: 3rem !important; -} - -.py-6 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; -} - -.p-auto { - padding: auto !important; -} - -.pt-auto { - padding-top: auto !important; -} - -.pr-auto { - padding-right: auto !important; -} - -.pb-auto { - padding-bottom: auto !important; -} - -.pl-auto { - padding-left: auto !important; -} - -.px-auto { - padding-left: auto !important; - padding-right: auto !important; -} - -.py-auto { - padding-top: auto !important; - padding-bottom: auto !important; -} - -.display-docked { - position: absolute; - opacity: 0; - z-index: 9999; - visibility: hidden; -} - -.confirmation-btns { - margin-left: auto; -} - -/* This is needed for some mobile phones to display the Google Icon font properly */ -.material-icons, .material-symbols-outlined, -.material-symbols-rounded, .material-symbols-sharp { - text-rendering: optimizeLegibility; - -webkit-font-feature-settings: "liga"; - -moz-font-feature-settings: "liga"; - font-feature-settings: "liga"; -} - -.container { - margin: 0 auto; - max-width: 1280px; - width: 90%; -} - -@media only screen and (min-width : 601px) { - .container { - width: 85%; - } -} -@media only screen and (min-width : 993px) { - .container { - width: 70%; - } -} -.section { - padding: 1rem 0; -} - -body { - --gap-size: 1.5rem; -} - -.row { - display: grid; - grid-template-columns: repeat(12, 1fr); - gap: var(--gap-size); -} -.row .s1 { - grid-column: auto/span 1; -} -.row .s2 { - grid-column: auto/span 2; -} -.row .s3 { - grid-column: auto/span 3; -} -.row .s4 { - grid-column: auto/span 4; -} -.row .s5 { - grid-column: auto/span 5; -} -.row .s6 { - grid-column: auto/span 6; -} -.row .s7 { - grid-column: auto/span 7; -} -.row .s8 { - grid-column: auto/span 8; -} -.row .s9 { - grid-column: auto/span 9; -} -.row .s10 { - grid-column: auto/span 10; -} -.row .s11 { - grid-column: auto/span 11; -} -.row .s12 { - grid-column: auto/span 12; -} -.row .offset-s1 { - grid-column-start: 3; -} -.row .offset-s2 { - grid-column-start: 2; -} -.row .offset-s3 { - grid-column-start: 4; -} -.row .offset-s4 { - grid-column-start: 5; -} -.row .offset-s5 { - grid-column-start: 6; -} -.row .offset-s6 { - grid-column-start: 7; -} -.row .offset-s7 { - grid-column-start: 8; -} -.row .offset-s8 { - grid-column-start: 9; -} -.row .offset-s9 { - grid-column-start: 10; -} -.row .offset-s10 { - grid-column-start: 11; -} -.row .offset-s11 { - grid-column-start: 12; -} -@media only screen and (min-width : 601px) { - .row .m1 { - grid-column: auto/span 1; - } - .row .m2 { - grid-column: auto/span 2; - } - .row .m3 { - grid-column: auto/span 3; - } - .row .m4 { - grid-column: auto/span 4; - } - .row .m5 { - grid-column: auto/span 5; - } - .row .m6 { - grid-column: auto/span 6; - } - .row .m7 { - grid-column: auto/span 7; - } - .row .m8 { - grid-column: auto/span 8; - } - .row .m9 { - grid-column: auto/span 9; - } - .row .m10 { - grid-column: auto/span 10; - } - .row .m11 { - grid-column: auto/span 11; - } - .row .m12 { - grid-column: auto/span 12; - } - .row .offset-m1 { - grid-column-start: 2; - } - .row .offset-m2 { - grid-column-start: 3; - } - .row .offset-m3 { - grid-column-start: 4; - } - .row .offset-m4 { - grid-column-start: 5; - } - .row .offset-m5 { - grid-column-start: 6; - } - .row .offset-m6 { - grid-column-start: 7; - } - .row .offset-m7 { - grid-column-start: 8; - } - .row .offset-m8 { - grid-column-start: 9; - } - .row .offset-m9 { - grid-column-start: 10; - } - .row .offset-m10 { - grid-column-start: 11; - } - .row .offset-m11 { - grid-column-start: 12; - } -} -@media only screen and (min-width : 993px) { - .row .l1 { - grid-column: auto/span 1; - } - .row .l2 { - grid-column: auto/span 2; - } - .row .l3 { - grid-column: auto/span 3; - } - .row .l4 { - grid-column: auto/span 4; - } - .row .l5 { - grid-column: auto/span 5; - } - .row .l6 { - grid-column: auto/span 6; - } - .row .l7 { - grid-column: auto/span 7; - } - .row .l8 { - grid-column: auto/span 8; - } - .row .l9 { - grid-column: auto/span 9; - } - .row .l10 { - grid-column: auto/span 10; - } - .row .l11 { - grid-column: auto/span 11; - } - .row .l12 { - grid-column: auto/span 12; - } - .row .offset-l1 { - grid-column-start: 2; - } - .row .offset-l2 { - grid-column-start: 3; - } - .row .offset-l3 { - grid-column-start: 4; - } - .row .offset-l4 { - grid-column-start: 5; - } - .row .offset-l5 { - grid-column-start: 6; - } - .row .offset-l6 { - grid-column-start: 7; - } - .row .offset-l7 { - grid-column-start: 8; - } - .row .offset-l8 { - grid-column-start: 9; - } - .row .offset-l9 { - grid-column-start: 10; - } - .row .offset-l10 { - grid-column-start: 11; - } - .row .offset-l11 { - grid-column-start: 12; - } -} -@media only screen and (min-width : 1201px) { - .row .xl1 { - grid-column: auto/span 1; - } - .row .xl2 { - grid-column: auto/span 2; - } - .row .xl3 { - grid-column: auto/span 3; - } - .row .xl4 { - grid-column: auto/span 4; - } - .row .xl5 { - grid-column: auto/span 5; - } - .row .xl6 { - grid-column: auto/span 6; - } - .row .xl7 { - grid-column: auto/span 7; - } - .row .xl8 { - grid-column: auto/span 8; - } - .row .xl9 { - grid-column: auto/span 9; - } - .row .xl10 { - grid-column: auto/span 10; - } - .row .xl11 { - grid-column: auto/span 11; - } - .row .xl12 { - grid-column: auto/span 12; - } - .row .offset-xl1 { - grid-column-start: 2; - } - .row .offset-xl2 { - grid-column-start: 3; - } - .row .offset-xl3 { - grid-column-start: 4; - } - .row .offset-xl4 { - grid-column-start: 5; - } - .row .offset-xl5 { - grid-column-start: 6; - } - .row .offset-xl6 { - grid-column-start: 7; - } - .row .offset-xl7 { - grid-column-start: 8; - } - .row .offset-xl8 { - grid-column-start: 9; - } - .row .offset-xl9 { - grid-column-start: 10; - } - .row .offset-xl10 { - grid-column-start: 11; - } - .row .offset-xl11 { - grid-column-start: 12; - } -} - -.g-0 { - gap: 0; -} - -.g-1 { - gap: calc(0.25 * var(--gap-size)); -} - -.g-2 { - gap: calc(0.5 * var(--gap-size)); -} - -.g-3 { - gap: calc(1 * var(--gap-size)); -} - -.g-4 { - gap: calc(1.5 * var(--gap-size)); -} - -.g-5 { - gap: calc(3 * var(--gap-size)); -} - -.scale-transition { - -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; - transition: -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; - transition: transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; - transition: transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63), -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; -} - -.scale-transition.scale-out { - -webkit-transform: scale(0); - transform: scale(0); - -webkit-transition: -webkit-transform 0.2s !important; - transition: -webkit-transform 0.2s !important; - transition: transform 0.2s !important; - transition: transform 0.2s, -webkit-transform 0.2s !important; -} - -.scale-transition.scale-in { - -webkit-transform: scale(1); - transform: scale(1); -} - -.pulse { - overflow: visible; - position: relative; - &::before { - content: ""; - display: block; - position: absolute; - pointer-events: none; - width: 100%; - height: 100%; - top: 0; - left: 0; - background-color: inherit; - border-radius: inherit; - -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; - transition: opacity 0.3s, -webkit-transform 0.3s; - transition: opacity 0.3s, transform 0.3s; - transition: opacity 0.3s, transform 0.3s, -webkit-transform 0.3s; - -webkit-animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; - animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; - z-index: -1; - } -} - -@-webkit-keyframes pulse-animation { - 0% { - opacity: 1; - -webkit-transform: scale(1); - transform: scale(1); - } - 50% { - opacity: 0; - -webkit-transform: scale(1.5); - transform: scale(1.5); - } - 100% { - opacity: 0; - -webkit-transform: scale(1.5); - transform: scale(1.5); - } -} - -@keyframes pulse-animation { - 0% { - opacity: 1; - -webkit-transform: scale(1); - transform: scale(1); - } - 50% { - opacity: 0; - -webkit-transform: scale(1.5); - transform: scale(1.5); - } - 100% { - opacity: 0; - -webkit-transform: scale(1.5); - transform: scale(1.5); - } -} -.table-of-contents { - list-style: none; -} -.table-of-contents.fixed { - position: fixed; -} -.table-of-contents li { - padding: 0; -} -.table-of-contents a { - display: inline-block; - font-weight: 400; - color: var(--md-sys-color-secondary); - padding-left: 16px; - height: 2rem; - line-height: 2rem; - border-left: 1px solid var(--md-sys-color-outline-variant); -} -.table-of-contents a:hover { - color: var(--md-sys-color-on-background); - padding-left: 15px; -} -.table-of-contents a.active { - color: var(--md-sys-color-primary); - font-weight: 500; - padding-left: 14px; - border-left: 2px solid var(--md-sys-color-primary); -} - -.tap-target-wrapper { - width: 800px; - height: 800px; - position: fixed; - z-index: 1000; - visibility: hidden; - -webkit-transition: visibility 0s 0.3s; - transition: visibility 0s 0.3s; -} - -.tap-target-wrapper.open { - visibility: visible; - -webkit-transition: visibility 0s; - transition: visibility 0s; -} -.tap-target-wrapper.open .tap-target { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 0.95; - -webkit-transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); - transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); - transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1); - transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); -} -.tap-target-wrapper.open .tap-target-wave::before { - -webkit-transform: scale(1); - transform: scale(1); -} -.tap-target-wrapper.open .tap-target-wave::after { - visibility: visible; - -webkit-animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; - animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; - -webkit-transition: opacity 0.3s, visibility 0s 1s, -webkit-transform 0.3s; - transition: opacity 0.3s, visibility 0s 1s, -webkit-transform 0.3s; - transition: opacity 0.3s, transform 0.3s, visibility 0s 1s; - transition: opacity 0.3s, transform 0.3s, visibility 0s 1s, -webkit-transform 0.3s; -} - -.tap-target { - position: absolute; - font-size: 1rem; - border-radius: 50%; - background-color: var(--md-sys-color-primary-container); - color: var(--md-sys-color-primary); - -webkit-box-shadow: 0 20px 20px 0 rgba(0, 0, 0, 0.14), 0 10px 50px 0 rgba(0, 0, 0, 0.12), 0 30px 10px -20px rgba(0, 0, 0, 0.2); - box-shadow: 0 20px 20px 0 rgba(0, 0, 0, 0.14), 0 10px 50px 0 rgba(0, 0, 0, 0.12), 0 30px 10px -20px rgba(0, 0, 0, 0.2); - width: 100%; - height: 100%; - opacity: 0; - -webkit-transform: scale(0); - transform: scale(0); - -webkit-transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); - transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); - transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1); - transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); -} - -.tap-target-content { - position: relative; - display: table-cell; -} - -.tap-target-wave { - position: absolute; - border-radius: 50%; - z-index: 10001; -} -.tap-target-wave::before, .tap-target-wave::after { - content: ""; - display: block; - position: absolute; - width: 100%; - height: 100%; - border-radius: 50%; - background-color: var(--md-sys-color-surface); -} -.tap-target-wave::before { - -webkit-transform: scale(0); - transform: scale(0); - -webkit-transition: -webkit-transform 0.3s; - transition: -webkit-transform 0.3s; - transition: transform 0.3s; - transition: transform 0.3s, -webkit-transform 0.3s; -} -.tap-target-wave::after { - visibility: hidden; - -webkit-transition: opacity 0.3s, visibility 0s, -webkit-transform 0.3s; - transition: opacity 0.3s, visibility 0s, -webkit-transform 0.3s; - transition: opacity 0.3s, transform 0.3s, visibility 0s; - transition: opacity 0.3s, transform 0.3s, visibility 0s, -webkit-transform 0.3s; - z-index: -1; -} - -.tap-target-origin { - top: 50%; - left: 50%; - z-index: 10002; - position: absolute !important; - -webkit-transform: translate(-50%, -50%); - transform: translate(-50%, -50%); -} -.tap-target-origin:not(.btn), .tap-target-origin:not(.btn):hover { - background: none; -} - -@media only screen and (max-width: 600px) { - .tap-target, .tap-target-wrapper { - width: 600px; - height: 600px; - } -} -:root { - --btn-height: 40px; - --btn-font-size-icon: 16px; - --btn-padding: 24px; - --btn-padding-icon: 16px; - --btn-gap-icon: 8px; - --btn-border-radius: 4px; - --btn-font-size: 14px; -} - -.btn, .btn-small, .btn-large, .btn-floating, .btn-flat { - height: var(--btn-height); - border-radius: var(--btn-border-radius); - padding-left: var(--btn-padding); - padding-right: var(--btn-padding); - font-size: var(--btn-font-size); - font-weight: 500; - text-decoration: none; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - border: none; - cursor: pointer; - -webkit-tap-highlight-color: transparent; - white-space: nowrap; - outline: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-transition: background-color 0.2s ease-out; - transition: background-color 0.2s ease-out; -} -.btn:focus, .btn-floating:focus, .btn-large:focus, .btn-small:focus, .btn-flat:focus { - background-color: var(--md-sys-color-primary-container); -} - -.btn.icon-left, .icon-left.btn-small, .icon-left.btn-large, .icon-left.btn-floating, .btn.icon-right, .icon-right.btn-small, .icon-right.btn-large, .icon-right.btn-floating { - position: relative; -} - -.btn.icon-left, .icon-left.btn-small, .icon-left.btn-large, .icon-left.btn-floating { - padding-left: calc(var(--btn-padding-icon) + var(--btn-font-size-icon) + var(--btn-gap-icon)); -} - -.btn.icon-right, .icon-right.btn-small, .icon-right.btn-large, .icon-right.btn-floating { - padding-right: calc(var(--btn-padding-icon) + var(--btn-font-size-icon) + var(--btn-gap-icon)); -} - -.btn.icon-left i, .icon-left.btn-small i, .icon-left.btn-large i, .icon-left.btn-floating i, .btn.icon-right i, .icon-right.btn-small i, .icon-right.btn-large i, .icon-right.btn-floating i { - position: absolute; - font-size: var(--btn-font-size-icon); -} - -.btn.icon-left i, .icon-left.btn-small i, .icon-left.btn-large i, .icon-left.btn-floating i { - left: var(--btn-padding-icon); -} - -.btn.icon-right i, .icon-right.btn-small i, .icon-right.btn-large i, .icon-right.btn-floating i { - right: var(--btn-padding-icon); -} - -.btn.filled, .filled.btn-small, .filled.btn-large, .filled.btn-floating { - color: var(--md-sys-color-on-primary); - background-color: var(--md-sys-color-primary); -} -.btn.filled:hover, .filled.btn-small:hover, .filled.btn-large:hover, .filled.btn-floating:hover, .btn.filled:focus, .filled.btn-small:focus, .filled.btn-large:focus, .filled.btn-floating:focus { - color: var(--md-sys-color-on-primary); -} -.btn.filled:hover, .filled.btn-small:hover, .filled.btn-large:hover, .filled.btn-floating:hover { - background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 16%); -} -.btn.filled:focus, .filled.btn-small:focus, .filled.btn-large:focus, .filled.btn-floating:focus { - background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 20%); -} -.btn.filled:focus-visible, .filled.btn-small:focus-visible, .filled.btn-large:focus-visible, .filled.btn-floating:focus-visible { - outline: 3px solid var(--md-sys-color-secondary); - outline-offset: 2px; -} - -.btn.tonal, .tonal.btn-small, .tonal.btn-large, .tonal.btn-floating { - color: var(--md-sys-color-on-secondary-container); - background-color: var(--md-sys-color-secondary-container); -} -.btn.tonal:hover, .tonal.btn-small:hover, .tonal.btn-large:hover, .tonal.btn-floating:hover, .btn.tonal:focus, .tonal.btn-small:focus, .tonal.btn-large:focus, .tonal.btn-floating:focus { - color: var(--md-sys-color-on-secondary-container); -} -.btn.tonal:hover, .tonal.btn-small:hover, .tonal.btn-large:hover, .tonal.btn-floating:hover { - background-color: color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-secondary-container) 16%); -} -.btn.tonal:focus, .tonal.btn-small:focus, .tonal.btn-large:focus, .tonal.btn-floating:focus { - background-color: color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-secondary-container) 20%); -} -.btn.tonal:focus-visible, .tonal.btn-small:focus-visible, .tonal.btn-large:focus-visible, .tonal.btn-floating:focus-visible { - outline: 3px solid var(--md-sys-color-secondary); - outline-offset: 2px; -} - -.btn.elevated:focus-visible, .elevated.btn-small:focus-visible, .elevated.btn-large:focus-visible, .elevated.btn-floating:focus-visible { - outline: 3px solid var(--md-sys-color-secondary); - outline-offset: 2px; -} - -.btn.outlined, .outlined.btn-small, .outlined.btn-large, .outlined.btn-floating { - background-color: transparent; - color: var(--md-sys-color-primary); - border: 1px solid var(--md-sys-color-outline); -} -.btn.outlined:hover, .outlined.btn-small:hover, .outlined.btn-large:hover, .outlined.btn-floating:hover, .btn.outlined:focus, .outlined.btn-small:focus, .outlined.btn-large:focus, .outlined.btn-floating:focus { - color: var(--md-sys-color-primary); -} -.btn.outlined:hover, .outlined.btn-small:hover, .outlined.btn-large:hover, .outlined.btn-floating:hover { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 16%); -} -.btn.outlined:focus, .outlined.btn-small:focus, .outlined.btn-large:focus, .outlined.btn-floating:focus { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%); - border: 1px solid var(--md-sys-color-primary); -} -.btn.outlined.disabled, .outlined.disabled.btn-small, .outlined.disabled.btn-large, .outlined.disabled.btn-floating { - background-color: unset; - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} -.btn.outlined:focus-visible, .outlined.btn-small:focus-visible, .outlined.btn-large:focus-visible, .outlined.btn-floating:focus-visible { - outline: 3px solid var(--md-sys-color-secondary); - outline-offset: 2px; -} - -.btn.text, .text.btn-small, .text.btn-large, .text.btn-floating, .btn-flat { - color: var(--md-sys-color-primary); - background-color: transparent; -} -.btn.text:hover, .text.btn-small:hover, .text.btn-large:hover, .text.btn-floating:hover, .btn.text:focus, .text.btn-small:focus, .text.btn-large:focus, .text.btn-floating:focus, .btn-flat:hover, .btn-flat:focus { - color: var(--md-sys-color-primary); -} -.btn.text:hover, .text.btn-small:hover, .text.btn-large:hover, .text.btn-floating:hover, .btn-flat:hover { - background-color: color-mix(in srgb, var(--md-sys-color-primary) 16%, transparent); -} -.btn.text:focus, .text.btn-small:focus, .text.btn-large:focus, .text.btn-floating:focus, .btn-flat:focus { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%); -} -.btn.text.disabled, .text.disabled.btn-small, .text.disabled.btn-large, .text.disabled.btn-floating, .btn-flat.disabled { - background-color: unset; -} -.btn.text:focus-visible, .text.btn-small:focus-visible, .text.btn-large:focus-visible, .text.btn-floating:focus-visible, .btn-flat:focus-visible { - outline: 3px solid var(--md-sys-color-secondary); - outline-offset: 2px; -} - -.btn.disabled, .btn-floating.disabled, .btn-large.disabled, .btn-small.disabled, .btn-flat.disabled, -.btn:disabled, .btn-floating:disabled, .btn-large:disabled, .btn-small:disabled, .btn-flat:disabled, -.btn[disabled], .btn-floating[disabled], .btn-large[disabled], .btn-small[disabled], .btn-flat[disabled] { - color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - background-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%); - pointer-events: none; - -webkit-box-shadow: none; - box-shadow: none; - cursor: default; -} - -.btn-floating { - width: 40px; - height: 40px; - color: var(--md-sys-color-on-primary-container); - background-color: var(--md-sys-color-primary-container); - border-radius: 16px; - padding: 0; - display: grid; - grid-auto-flow: column; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - position: relative; - overflow: hidden; - z-index: 1; - -webkit-transition: background-color 0.3s; - transition: background-color 0.3s; - cursor: pointer; - vertical-align: middle; - text-align: center; -} -.btn-floating:hover { - background-color: color-mix(in srgb, var(--md-sys-color-primary-container), var(--md-sys-color-on-primary-container) 16%); -} -.btn-floating:focus { - background-color: var(--md-ref-palette-secondary80); -} -.btn-floating:before { - border-radius: 0; -} -.btn-floating.btn-large { - width: 56px; - height: 56px; - padding: 0; -} -.btn-floating.btn-large.halfway-fab { - bottom: -28px; -} -.btn-floating.btn-small { - --btn-small-height: calc(0.75 * var(--btn-height)); - width: var(--btn-small-height); - height: var(--btn-small-height); -} -.btn-floating.btn-small.halfway-fab { - bottom: calc(var(--btn-small-height) * -0.5); -} -.btn-floating.halfway-fab { - position: absolute; - right: 24px; - bottom: -20px; -} -.btn-floating.halfway-fab.left { - right: auto; - left: 24px; -} -.btn-floating i { - color: currentColor; - font-size: 1.6rem; - width: inherit; - display: inline-block; - text-align: center; -} - -button.btn-floating { - border: none; -} - -.fixed-action-btn { - position: fixed; - right: 23px; - bottom: 23px; - padding-top: 15px; - margin-bottom: 0; - z-index: 997; -} -.fixed-action-btn.active ul { - visibility: visible; - padding-left: 0; - list-style-type: none; -} -.fixed-action-btn.direction-left, .fixed-action-btn.direction-right { - padding: 0 0 0 15px; -} -.fixed-action-btn.direction-left ul, .fixed-action-btn.direction-right ul { - text-align: right; - right: 64px; - top: 50%; - -webkit-transform: translateY(-50%); - transform: translateY(-50%); - height: 100%; - left: auto; - /*width 100% only goes to width of button container */ - width: 500px; -} -.fixed-action-btn.direction-left ul li, .fixed-action-btn.direction-right ul li { - display: inline-block; - margin: 7.5px 15px 0 0; -} -.fixed-action-btn.direction-right { - padding: 0 15px 0 0; -} -.fixed-action-btn.direction-right ul { - text-align: left; - direction: rtl; - left: 64px; - right: auto; -} -.fixed-action-btn.direction-right ul li { - margin: 7.5px 0 0 15px; -} -.fixed-action-btn.direction-bottom { - padding: 0 0 15px 0; -} -.fixed-action-btn.direction-bottom ul { - top: 64px; - bottom: auto; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: reverse; - -webkit-flex-direction: column-reverse; - -ms-flex-direction: column-reverse; - flex-direction: column-reverse; -} -.fixed-action-btn.direction-bottom ul li { - margin: 15px 0 0 0; -} -.fixed-action-btn.toolbar { - padding: 0; - height: 56px; -} -.fixed-action-btn.toolbar.active > a i { - opacity: 0; -} -.fixed-action-btn.toolbar ul { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - top: 0; - bottom: 0; - z-index: 1; -} -.fixed-action-btn.toolbar ul li { - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - display: inline-block; - margin: 0; - height: 100%; - -webkit-transition: none; - transition: none; -} -.fixed-action-btn.toolbar ul li a { - display: block; - overflow: hidden; - position: relative; - width: 100%; - height: 100%; - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; - color: var(--md-sys-color-on-secondary); - line-height: 56px; - z-index: 1; -} -.fixed-action-btn.toolbar ul li a i { - line-height: inherit; -} -.fixed-action-btn ul { - left: 0; - right: 0; - text-align: center; - position: absolute; - bottom: 64px; - margin: 0; - visibility: hidden; -} -.fixed-action-btn ul li { - margin-bottom: 15px; -} -.fixed-action-btn ul a.btn-floating { - opacity: 0; -} -.fixed-action-btn .fab-backdrop { - position: absolute; - top: 0; - left: 0; - z-index: -1; - width: 40px; - height: 40px; - background-color: var(--md-sys-color-secondary); - border-radius: 16px; - -webkit-transform: scale(0); - transform: scale(0); -} - -.btn-large { - height: calc(1.5 * var(--btn-height)); - font-size: 18px; - padding: 0 28px; -} -.btn-large i { - font-size: 1.6rem; -} - -.btn-small { - height: calc(0.75 * var(--btn-height)); - font-size: 13px; -} -.btn-small i { - font-size: 1.2rem; -} - -.btn-block { - display: block; -} - -.btn.rounded, .rounded.btn-floating, .rounded.btn-large, .rounded.btn-small { - border-radius: 99999px; -} - -.collapsible { - padding-left: 0; - list-style-type: none; - border-top: 1px solid var(--md-sys-color-outline-variant); - border-right: 1px solid var(--md-sys-color-outline-variant); - border-left: 1px solid var(--md-sys-color-outline-variant); - margin: 0.5rem 0 1rem 0; -} - -.collapsible-header { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - cursor: pointer; - -webkit-tap-highlight-color: transparent; - line-height: 1.5; - padding: 1rem; - border-bottom: 1px solid var(--md-sys-color-outline-variant); -} -.collapsible-header:focus { - outline: 0; -} -.collapsible-header i { - width: 2rem; - font-size: 1.6rem; - display: inline-block; - text-align: center; - margin-right: 1rem; -} - -.collapsible-header::after { - content: "\e5cf"; - margin-left: 0.5rem; - font-family: "Material Symbols Outlined", "Material Symbols Rounded", "Material Symbols Sharp", "Material Icons"; - font-size: 25px; - line-height: 0.9; - -webkit-font-smoothing: antialiased; -} - -.active .collapsible-header::after { - content: "\e5ce"; -} - -.keyboard-focused .collapsible-header:focus { - background-color: rgba(0, 0, 0, 0.12); -} - -.collapsible-header-content { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; -} - -.collapsible-body { - max-height: 0; - border-bottom: 1px solid var(--md-sys-color-outline-variant); - -webkit-box-sizing: border-box; - box-sizing: border-box; - padding: 0 2rem; - overflow: hidden; -} - -.collapsible.popout { - border: none; - -webkit-box-shadow: none; - box-shadow: none; -} -.collapsible.popout > li { - -webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); - margin: 0 24px; - -webkit-transition: margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94); - transition: margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94); -} -.collapsible.popout > li.active { - -webkit-box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15); - box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15); - margin: 16px 0; -} - -:root { - --bagde-height: 22px; -} - -span.badge { - min-width: 3rem; - padding: 0 6px; - margin-left: 14px; - text-align: center; - font-size: 1rem; - line-height: var(--bagde-height); - height: var(--bagde-height); - color: var(--md-sys-color-on-surface-variant); - float: right; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -span.badge.new { - font-weight: 300; - font-size: 0.8rem; - color: var(--md-sys-color-on-primary); - background-color: var(--md-sys-color-primary); - border-radius: 2px; -} -span.badge.new:after { - content: " new"; -} -span.badge[data-badge-caption]::after { - content: " " attr(data-badge-caption); -} - -.active span.badge { - color: var(--md-sys-color-on-primary); -} - -.navbar ul a span.badge { - display: inline-block; - float: none; - margin-left: 4px; - line-height: var(--bagde-height); - height: var(--bagde-height); - -webkit-font-smoothing: auto; -} - -.collection-item span.badge { - margin-top: calc(0.75rem - var(--bagde-height) * 0.5); -} - -.collapsible span.badge { - margin-left: auto; -} -.collapsible span.badge.leading { - margin-right: 7px; - -webkit-box-ordinal-group: 0; - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; -} - -.collapsible .active span.badge:not(.new) { - color: var(--md-sys-color-on-surface-variant); -} - -.sidenav span.badge { - margin-top: calc(var(--sidenav-line-height) * 0.5 - 11px); -} - -table span.badge { - display: inline-block; - float: none; - margin-left: auto; -} - -.card-panel { - -webkit-transition: -webkit-box-shadow 0.25s; - transition: -webkit-box-shadow 0.25s; - transition: box-shadow 0.25s; - transition: box-shadow 0.25s, -webkit-box-shadow 0.25s; - padding: 24px; - margin: 0.5rem 0 1rem 0; - border-radius: 12px; - background-color: var(--md-sys-color-surface); -} - -.card { - --background-color: color-mix(in srgb, var(--md-sys-color-surface), var(--md-sys-color-surface-tint) 17%); - position: relative; - background-color: var(--background-color); - -webkit-transition: -webkit-box-shadow 0.25s; - transition: -webkit-box-shadow 0.25s; - transition: box-shadow 0.25s; - transition: box-shadow 0.25s, -webkit-box-shadow 0.25s; - border-radius: 12px; -} -.card .card-title { - font-size: 24px; - font-weight: 300; -} -.card.small, .card.medium, .card.large { - position: relative; -} -.card.small .card-image, .card.medium .card-image, .card.large .card-image { - max-height: 60%; - overflow: hidden; -} -.card.small .card-image + .card-content, .card.medium .card-image + .card-content, .card.large .card-image + .card-content { - max-height: 40%; -} -.card.small .card-content, .card.medium .card-content, .card.large .card-content { - max-height: 100%; - overflow: hidden; -} -.card.small .card-action, .card.medium .card-action, .card.large .card-action { - position: absolute; - bottom: 0; - left: 0; - right: 0; -} -.card.small { - height: 300px; -} -.card.medium { - height: 400px; -} -.card.large { - height: 500px; -} -.card.horizontal { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} -.card.horizontal.small .card-image, .card.horizontal.medium .card-image, .card.horizontal.large .card-image { - height: 100%; - max-height: none; - overflow: visible; -} -.card.horizontal.small .card-image img, .card.horizontal.medium .card-image img, .card.horizontal.large .card-image img { - height: 100%; -} -.card.horizontal .card-image { - max-width: 50%; -} -.card.horizontal .card-image img { - border-radius: 2px 0 0 2px; - max-width: 100%; - width: auto; -} -.card.horizontal .card-stacked { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - position: relative; -} -.card.horizontal .card-stacked .card-content { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; -} -.card.sticky-action .card-action { - z-index: 2; -} -.card.sticky-action .card-reveal { - z-index: 1; - padding-bottom: 64px; -} -.card .card-image { - position: relative; -} -.card .card-image img { - display: block; - border-radius: 2px 2px 0 0; - position: relative; - left: 0; - right: 0; - top: 0; - bottom: 0; - width: 100%; -} -.card .card-image .card-title { - color: var(--md-sys-color-surface); - position: absolute; - bottom: 0; - left: 0; - max-width: 100%; - padding: 24px; -} -.card .card-image .activator { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - cursor: pointer; -} -.card .card-image img.activator { - position: relative; -} -.card .card-content { - padding: 24px; - border-radius: 0 0 2px 2px; -} -.card .card-content p { - margin: 0; -} -.card .card-content .card-title { - display: block; - line-height: 32px; - margin-bottom: 8px; -} -.card .card-content .card-title i { - line-height: 32px; -} -.card .card-content .card-title.activator { - cursor: pointer; -} -.card .card-action { - padding: 0 1.6rem; -} -.card .card-action:last-child { - border-radius: 0 0 2px 2px; -} -.card .card-action a { - height: var(--btn-height); - border-radius: var(--btn-border-radius); - padding-left: var(--btn-padding); - padding-right: var(--btn-padding); - font-size: var(--btn-font-size); - font-weight: 500; - text-decoration: none; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - border: none; - cursor: pointer; - -webkit-tap-highlight-color: transparent; - white-space: nowrap; - outline: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-transition: background-color 0.2s ease-out; - transition: background-color 0.2s ease-out; -} -.card .card-action a:focus { - background-color: var(--md-sys-color-primary-container); -} -.card .card-action a:first-child { - margin-left: -1.6rem; -} -.card .card-action a:last-child { - margin-right: -1.6rem; -} -.card .card-action .btn.filled, .card .card-action .btn.tonal, .card .card-action .btn.elevated, .card .card-action .btn.outlined { - margin: 0 0.26rem 1.6rem 0; -} -.card .card-reveal { - padding: 24px; - position: absolute; - background-color: var(--md-sys-color-surface); - width: 100%; - overflow-y: auto; - left: 0; - top: 100%; - height: 100%; - z-index: 3; - display: none; -} -.card .card-reveal .card-title { - cursor: pointer; - display: block; -} - -#toast-container { - display: block; - position: fixed; - z-index: 10000; -} -@media only screen and (max-width : 600.99px) { - #toast-container { - min-width: 100%; - bottom: 0%; - } -} -@media only screen and (min-width : 601px) and (max-width : 992.99px) { - #toast-container { - left: 5%; - bottom: 7%; - max-width: 90%; - } -} -@media only screen and (min-width : 993px) { - #toast-container { - top: 10%; - right: 7%; - max-width: 86%; - } -} - -.toast { - border-radius: 4px; - top: 35px; - width: auto; - margin-top: 10px; - position: relative; - max-width: 100%; - height: auto; - min-height: 48px; - padding-left: 16px; - padding-right: 12px; - font-size: 14px; - font-weight: 500; - line-height: 20px; - color: var(--md-sys-color-inverse-on-surface); - background-color: var(--md-sys-color-inverse-surface); - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - cursor: default; -} -.toast .toast-action { - color: var(--md-sys-color-inverse-primary); - font-weight: 500; - margin-right: -25px; - margin-left: 3rem; -} -.toast.rounded { - border-radius: 24px; -} -@media only screen and (max-width : 600.99px) { - .toast { - width: 100%; - border-radius: 0; - } -} - -.tabs { - padding-left: 0; - list-style-type: none; - position: relative; - overflow-x: auto; - overflow-y: hidden; - width: 100%; - background-color: var(--md-sys-color-surface); - margin: 0 auto; - white-space: nowrap; - scrollbar-width: none; -} -.tabs.tabs-transparent { - background-color: transparent; -} -.tabs.tabs-transparent .tab a { - color: var(--font-on-primary-color-medium); -} -.tabs.tabs-transparent .tab.disabled a, -.tabs.tabs-transparent .tab.disabled a:hover, -.tabs.tabs-transparent .tab.disabled a:focus { - color: rgba(255, 255, 255, 0.38); -} -.tabs.tabs-transparent .tab a:hover { - background-color: rgba(0, 0, 0, 0.04); -} -.tabs.tabs-transparent .tab a.active, -.tabs.tabs-transparent .tab a:focus { - background-color: transparent; -} -.tabs.tabs-transparent .tab a:hover, -.tabs.tabs-transparent .tab a.active, -.tabs.tabs-transparent .tab a:focus { - color: var(--md-sys-color-on-primary); -} -.tabs.tabs-transparent .indicator { - background-color: var(--md-sys-color-on-primary); -} -.tabs.tabs-fixed-width { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} -.tabs.tabs-fixed-width .tab { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; -} -.tabs .tab { - padding-left: 0; - list-style-type: none; - display: inline-block; - text-align: center; - line-height: 48px; - padding: 0; - margin: 0; -} -.tabs .tab i.material-icons { - position: relative; - top: 8px; - vertical-align: middle; -} -.tabs .tab span { - height: 24px; - line-height: 20px; -} -.tabs .tab a { - color: var(--md-sys-color-on-surface-variant); - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - width: 100%; - height: 100%; - min-height: 48px; - padding: 0 24px; - font-size: 14px; - text-overflow: ellipsis; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - overflow: hidden; - -webkit-transition: color 0.28s ease, background-color 0.28s ease; - transition: color 0.28s ease, background-color 0.28s ease; -} -.tabs .tab a.active { - background-color: transparent; -} -.tabs .tab a.active, .tabs .tab a:focus, .tabs .tab a:hover { - color: var(--md-sys-color-primary); -} -.tabs .tab a:hover { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%); -} -.tabs .tab a:focus { - background-color: var(--md-sys-color-primary-container); -} -.tabs .tab a.active { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); -} -.tabs .tab a:focus, .tabs .tab a.active { - outline: none; -} -.tabs .tab.disabled a, .tabs .tab.disabled a:hover { - color: var(--md-sys-color-on-surface); - cursor: default; - background-color: transparent; -} -.tabs .tab.disabled a:not(:focus), .tabs .tab.disabled a:hover:not(:focus) { - background-color: transparent; -} -.tabs .indicator { - position: absolute; - bottom: 0; - height: 3px; - background-color: var(--md-sys-color-primary); - will-change: left, right; - border-radius: 3px 3px 0 0; -} -.tabs.tabs-horizontal .tab { - height: 48px; -} -.tabs.tabs-horizontal .tab a { - display: block; -} -.tabs.tabs-horizontal .tab i.material-icons { - padding: 0 4px; - position: relative; - top: -2px; - vertical-align: middle; -} - -/* Fixed Sidenav hide on smaller */ -@media only screen and (max-width : 992.99px) { - .tabs { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - } - .tabs .tab { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - } - .tabs .tab a { - padding: 0 12px; - } -} -.material-tooltip { - padding: 0 8px; - border-radius: 4px; - color: var(--md-sys-color-inverse-on-surface); - background-color: var(--md-sys-color-inverse-surface); - font-family: var(--md-sys-typescale-body-small-font-family-name); - font-size: var(--md-sys-typescale-body-small-font-size); - line-height: var(--md-sys-typescale-body-small-line-height); - font-weight: var(--md-sys-typescale-body-small-font-weight); - min-height: 24px; - opacity: 0; - padding-top: 6px; - padding-bottom: 6px; - font-size: 12px; - line-height: 16px; - font-weight: 400; - letter-spacing: 0.4px; - position: absolute; - max-width: 300px; - overflow: hidden; - left: 0; - top: 0; - pointer-events: none; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - visibility: hidden; - z-index: 2000; -} - -.backdrop { - position: absolute; - opacity: 0; - height: 7px; - width: 14px; - border-radius: 0 0 50% 50%; - background-color: var(--md-sys-color-inverse-surface); - z-index: -1; - -webkit-transform-origin: 50% 0; - transform-origin: 50% 0; - visibility: hidden; -} - -[popover] { - outline: none; - padding: 0; - border: none; -} - -.dropdown-content { - padding-left: 0; - list-style-type: none; - background-color: var(--md-sys-color-surface); - margin: 0; - display: none; - min-width: 100px; - overflow-y: auto; - opacity: 0; - position: absolute; - left: 0; - top: 0; - z-index: 9999; - -webkit-transform-origin: 0 0; - transform-origin: 0 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - white-space: nowrap; -} -.dropdown-content li { - clear: both; - color: var(--md-sys-color-on-background); - cursor: pointer; - min-height: 50px; - line-height: 1.5rem; - width: 100%; - text-align: left; -} -.dropdown-content li.divider { - min-height: 0; - height: 1px; -} -.dropdown-content li > a, .dropdown-content li > span { - font-size: 16px; - color: var(--md-sys-color-primary); - display: block; - line-height: 22px; - padding: 14px 16px; -} -.dropdown-content li > span > label { - top: 1px; - left: 0; - height: 18px; -} -.dropdown-content li > a > i { - height: inherit; - line-height: inherit; - float: left; - margin: 0 24px 0 0; - width: 24px; -} -.dropdown-content li:not(.disabled):hover, .dropdown-content li.active { - background-color: color-mix(in srgb, var(--md-sys-color-surface), var(--md-sys-color-on-surface) 8%); -} - -body.keyboard-focused .dropdown-content li:focus { - background-color: rgba(0, 0, 0, 0.12); -} - -.input-field.col .dropdown-content [type=checkbox] + label { - top: 1px; - left: 0; - height: 18px; - -webkit-transform: none; - transform: none; -} - -.dropdown-trigger { - cursor: pointer; -} - -.collection { - padding-left: 0; - list-style-type: none; - margin: 0.5rem 0 1rem 0; - border: 1px solid var(--md-sys-color-outline-variant); - border-radius: 2px; - overflow: hidden; - position: relative; -} -.collection .collection-item { - background-color: transparent; - line-height: 1.5rem; - padding: 10px 20px; - margin: 0; - border-bottom: 1px solid var(--md-sys-color-outline-variant); -} -.collection .collection-item.avatar { - min-height: 84px; - padding-left: 72px; - position: relative; -} -.collection .collection-item.avatar:not(.circle-clipper) > .circle, -.collection .collection-item.avatar :not(.circle-clipper) > .circle { - position: absolute; - width: 42px; - height: 42px; - overflow: hidden; - left: 15px; - display: inline-block; - vertical-align: middle; -} -.collection .collection-item.avatar i.circle { - font-size: 18px; - line-height: 42px; - color: #fff; - background-color: var(--md-sys-color-shadow-light); - text-align: center; -} -.collection .collection-item.avatar .title { - font-size: 16px; -} -.collection .collection-item.avatar p { - margin: 0; -} -.collection .collection-item.avatar .secondary-content { - position: absolute; - top: 16px; - right: 16px; -} -.collection .collection-item:last-child { - border-bottom: none; -} -.collection .collection-item.active { - background-color: var(--md-sys-color-primary); - color: var(--md-sys-color-on-primary); -} -.collection .collection-item.active .secondary-content { - color: var(--md-sys-color-on-primary); -} -.collection a.collection-item { - display: block; - -webkit-transition: 0.25s; - transition: 0.25s; - color: var(--md-sys-color-primary); -} -.collection a.collection-item:not(.active):hover { - background-color: rgba(0, 0, 0, 0.04); -} -.collection.with-header .collection-header { - background-color: transparent; - border-bottom: 1px solid var(--md-sys-color-outline-variant); - padding: 10px 20px; -} -.collection.with-header .collection-item { - padding-left: 30px; -} -.collection.with-header .collection-item.avatar { - padding-left: 72px; -} - -.secondary-content { - float: right; - color: var(--md-sys-color-primary); -} - -.collapsible .collection { - margin: 0; - border: none; -} - -.list-item { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.modal { - --modal-footer-divider-height: 1px; - --modal-border-radius: 28px; - --modal-padding: 24px; - --modal-padding-bottom: 16px; - --modal-background-color: color-mix(in srgb, var(--md-sys-color-surface), var(--md-sys-color-surface-tint) 17%); - border: none; - outline: none; - padding: 0; - max-height: 70%; - width: 55%; - border-radius: var(--modal-border-radius); - will-change: top, opacity; - background-color: var(--modal-background-color); -} -.modal[open] { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} -@media only screen and (max-width : 992.99px) { - .modal { - width: 80%; - } -} -.modal::-webkit-backdrop { - -webkit-backdrop-filter: blur(1px); - backdrop-filter: blur(1px); -} -.modal::-ms-backdrop { - backdrop-filter: blur(1px); -} -.modal::backdrop { - -webkit-backdrop-filter: blur(1px); - backdrop-filter: blur(1px); -} -.modal .modal-header { - padding: var(--modal-padding); - padding-bottom: var(--modal-padding-bottom); - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - position: -webkit-sticky; - position: sticky; - top: 0; -} -.modal .modal-content { - padding: 0 var(--modal-padding); -} -.modal .modal-footer { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - border-radius: 0 0 var(--modal-border-radius) var(--modal-border-radius); - padding: var(--modal-padding); - text-align: right; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - position: -webkit-sticky; - position: sticky; - bottom: 0; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} -.modal .modal-close { - cursor: pointer; -} -.modal h1, .modal h2, .modal h3, .modal h4, .modal h5, .modal h6 { - margin: 0; -} - -.modal.bottom-sheet { - margin-bottom: 0; - max-height: 45%; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - will-change: bottom, opacity; -} - -.materialboxed { - display: block; - cursor: -webkit-zoom-in; - cursor: zoom-in; - position: relative; - -webkit-transition: opacity 0.4s; - transition: opacity 0.4s; - -webkit-backface-visibility: hidden; -} -.materialboxed:hover:not(.active) { - opacity: 0.8; -} -.materialboxed.active { - cursor: -webkit-zoom-out; - cursor: zoom-out; -} - -#materialbox-overlay { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - background-color: var(--md-sys-color-background); - z-index: 1000; - will-change: opacity; -} - -.materialbox-caption { - position: fixed; - display: none; - color: var(--md-sys-color-on-background); - line-height: 50px; - bottom: 0; - left: 0; - width: 100%; - text-align: center; - padding: 0% 15%; - height: 50px; - z-index: 1000; - -webkit-font-smoothing: antialiased; -} - -.chip { - --font-size: 14px; - --font-size-icon: 18px; - --padding: 8px; - color: var(--md-sys-color-on-surface-variant); - background-color: rgba(0, 0, 0, 0.09); - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - white-space: nowrap; - gap: 8px; - margin: 0; - height: 32px; - padding-left: var(--padding); - padding-right: var(--padding); - font-size: var(--font-size); - font-weight: 500; - border-radius: 8px; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - vertical-align: top; -} - -.chip:focus { - outline: none; - background-color: var(--md-sys-color-primary); - color: var(--md-sys-color-on-primary); -} - -.chip.outlined { - background-color: transparent; - border-color: var(--md-sys-color-outline); - border-width: 1px; - border-style: solid; -} - -.chip > img { - margin: 0; - width: 24px; - height: 24px; - -o-object-fit: cover; - object-fit: cover; - border-radius: 12px; -} - -.chip > .material-icons { - font-size: var(--font-size-icon); - color: var(--md-sys-color-on-surface-variant); -} - -.chip .close { - border: none; - border-radius: 50%; - height: 24px; - width: 24px; - padding: 0; - display: grid; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - cursor: pointer; -} - -.chip .close:hover { - background-color: rgba(136, 136, 136, 0.5333333333); -} - -.chips { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - gap: 4px; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - border: none; - -webkit-box-shadow: none; - box-shadow: none; - margin: 0 0 8px 0; - padding: 4px; - /* min-height: 45px; */ - outline: none; - -webkit-transition: all 0.3s; - transition: all 0.3s; -} - -.chips.focus { - border-bottom: 1px solid var(--md-sys-color-primary); - -webkit-box-shadow: 0 1px 0 0 var(--md-sys-color-primary); - box-shadow: 0 1px 0 0 var(--md-sys-color-primary); -} - -.chips.input-field { - border-bottom: 1px solid var(--md-sys-color-on-surface-variant); -} - -.chis input:not([type]):not(.browser-default).input { - background: none; - border: 0; - color: var(--md-sys-color-on-background); - display: inline-block; - font-size: 16px; - /* height: 32px; - line-height: 32px; */ - height: 32px; - outline: 0; - margin: 0; - padding: 0; - width: 120px; - width: -webkit-fit-content; - width: -moz-fit-content; - width: fit-content; - min-width: 100px; - max-width: 200px; -} - -.chis input:not([type]):not(.browser-default).input:focus { - border: 0; - -webkit-box-shadow: none; - box-shadow: none; -} - -.chips.input-field:hover { - cursor: text; -} - -.chips .autocomplete-content { - margin-top: 0; - margin-bottom: 0; -} - -.prefix ~ .chips { - margin-left: 3rem; - width: 92%; - width: calc(100% - 3rem); -} - -.suffix ~ .chips { - margin-right: 3rem; - width: 92%; - width: calc(100% - 3rem); -} - -.chips:empty ~ label { - font-size: 0.8rem; - -webkit-transform: translateY(-140%); - transform: translateY(-140%); -} - -:root { - --navbar-height: 64px; - --navbar-height-mobile: 56px; - --appbar-title-font-size: 24px; -} - -.nav-wrapper { - height: 100%; - background-color: var(--md-sys-color-surface); - padding-left: 4px; - padding-right: 4px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; -} - -.navbar { - color: var(--md-sys-color-on-surface); - height: var(--navbar-height-mobile); -} - -.navbar ul:not(.dropdown-content) { - list-style-type: none; - margin: 0; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - gap: 1em; -} - -.navbar ul:not(.dropdown-content) > li { - -webkit-transition: background-color 0.3s; - transition: background-color 0.3s; - padding: 0; -} - -.navbar ul:not(.dropdown-content) > li > a { - -webkit-transition: background-color 0.3s; - transition: background-color 0.3s; - color: var(--md-sys-color-on-surface); - display: block; - cursor: pointer; -} - -.navbar .brand-logo { - color: var(--md-sys-color-on-surface); - font-size: var(--appbar-title-font-size); - display: inline-block; - padding: 0; -} - -.navbar .nav-title { - display: inline-block; - font-size: 32px; - padding: 28px 0; -} - -.navbar-fixed { - position: fixed; - z-index: 997; -} - -.sidenav { - --sidenav-width: 300px; - --sidenav-font-size: 14px; - --sidenav-padding: 16px; - --sidenav-item-height: 48px; - --sidenav-line-height: var(--sidenav-item-height); - position: fixed; - width: var(--sidenav-width); - left: 0; - top: 0; - margin: 0; - -webkit-transform: translateX(-100%); - transform: translateX(-100%); - height: 100vh; - padding: 0; - z-index: 999; - overflow-y: auto; - will-change: transform; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-transform: translateX(-105%); - transform: translateX(-105%); - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - color: var(--md-sys-color-on-secondary-container); - background-color: var(--md-sys-color-surface); -} -.sidenav.right-aligned { - right: 0; - -webkit-transform: translateX(105%); - transform: translateX(105%); - left: auto; - -webkit-transform: translateX(100%); - transform: translateX(100%); -} -.sidenav .collapsible { - margin: 0; -} -.sidenav { - /* Hover only on top row */ - /*a:hover { - //color: red; - //background-color: var(--md-sys-color-on-secondary-container); - //md.sys.color.on-secondary-container - }*/ -} -.sidenav a:focus { - background-color: rgba(0, 0, 0, 0.12); -} -.sidenav li.active > a:not(.collapsible-header):not(.btn):not(.btn-large):not(.btn-small):not(.btn-flat):not(.btn-large):not(.btn-floating) { - background-color: color-mix(in srgb, var(--md-sys-color-secondary) 10%, transparent); -} -.sidenav .collapsible-body > ul { - padding-left: 10px; -} -.sidenav li { - list-style: none; - display: grid; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; -} -.sidenav li > a { - /* https://stackoverflow.com/questions/5848090/full-width-hover-background-for-nested-lists */ - margin: 0 12px; - padding: 0 var(--sidenav-padding); - /* - min-width: 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - */ - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - height: var(--sidenav-item-height); - font-size: var(--sidenav-font-size); - font-weight: 500; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - overflow: hidden; - border-radius: 100px; -} -.sidenav li > a:not(.btn):not(.btn-flat):not(.btn-large):not(.btn-floating) { - color: var(--md-sys-color-on-secondary-container); -} -.sidenav li > a:not(.btn):not(.btn-flat):not(.btn-large):not(.btn-floating):hover { - background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); -} -.sidenav li > a.btn, .sidenav li > a.btn-large, .sidenav li > a.btn-flat, .sidenav li > a.btn-floating { - margin: 10px 15px; -} -.sidenav li > a { - /* TODO: Use special class in future like "mw-icon" */ -} -.sidenav li > a > .material-icons, .sidenav li > a > .material-symbols-outlined, .sidenav li > a > .material-symbols-rounded, .sidenav li > a > .material-symbols-sharp { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - vertical-align: middle; - margin-right: 12px; -} -.sidenav .divider { - margin: calc(var(--sidenav-padding) * 0.5) 0 0 0; -} -.sidenav .subheader { - cursor: initial; - pointer-events: none; - color: red; - font-size: var(--sidenav-font-size); - font-weight: 500; - line-height: var(--sidenav-line-height); -} -.sidenav .user-view { - position: relative; - padding: calc(var(--sidenav-padding) * 2) calc(var(--sidenav-padding) * 2) 0; - margin-bottom: calc(var(--sidenav-padding) * 0.5); -} -.sidenav .user-view > a { - height: auto; - padding: 0; -} -.sidenav .user-view > a:hover { - background-color: transparent; -} -.sidenav .user-view .background { - overflow: hidden; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: -1; -} -.sidenav .user-view .circle, .sidenav .user-view .name, .sidenav .user-view .email { - display: block; -} -.sidenav .user-view .circle { - height: 64px; - width: 64px; -} -.sidenav .user-view .name, -.sidenav .user-view .email { - font-size: var(--sidenav-font-size); - line-height: calc(var(--sidenav-line-height) * 0.5); -} -.sidenav .user-view .name { - margin-top: 16px; - font-weight: 500; -} -.sidenav .user-view .email { - padding-bottom: 16px; - font-weight: 400; -} - -.drag-target { - height: 100%; - position: fixed; - top: 0; - left: 0; - z-index: 998; -} -.drag-target.right-aligned { - right: 0; -} - -.sidenav.sidenav-fixed { - left: 0; - -webkit-transform: translateX(0); - transform: translateX(0); - position: fixed; -} -.sidenav.sidenav-fixed.right-aligned { - right: 0; - left: auto; -} - -@media only screen and (max-width : 992.99px) { - .sidenav.sidenav-fixed { - -webkit-transform: translateX(-105%); - transform: translateX(-105%); - } - .sidenav.sidenav-fixed.right-aligned { - -webkit-transform: translateX(105%); - transform: translateX(105%); - } - .sidenav > a { - padding: 0 var(--sidenav-padding); - } - .sidenav .user-view { - padding: var(--sidenav-padding) var(--sidenav-padding) 0; - } -} -.sidenav .collapsible-body { - padding: 0; -} - -.sidenav-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - opacity: 0; - height: 120vh; - background-color: rgba(0, 0, 0, 0.5); - z-index: 997; - display: none; -} - -.sidenav .collapsible, -.sidenav.sidenav-fixed .collapsible { - border: none; - -webkit-box-shadow: none; - box-shadow: none; -} -.sidenav .collapsible-header, -.sidenav.sidenav-fixed .collapsible-header { - border: none; -} -.sidenav .collapsible-body, -.sidenav.sidenav-fixed .collapsible-body { - border: none; -} - -.progress { - position: relative; - height: 4px; - display: block; - width: 100%; - background-color: var(--md-sys-color-surface-variant); - border-radius: 4px; - margin: 0.5rem 0 1rem 0; - overflow: hidden; - background-color: var(--md-sys-color-secondary-container); -} -.progress .determinate { - position: absolute; - top: 0; - left: 0; - bottom: 0; - background-color: var(--md-sys-color-primary); - -webkit-transition: width 0.3s linear; - transition: width 0.3s linear; -} -.progress .indeterminate { - background-color: var(--md-sys-color-primary); -} -.progress .indeterminate:before { - content: ""; - position: absolute; - background-color: inherit; - top: 0; - left: 0; - bottom: 0; - will-change: left, right; - -webkit-animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; - animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; -} -.progress .indeterminate:after { - content: ""; - position: absolute; - background-color: inherit; - top: 0; - left: 0; - bottom: 0; - will-change: left, right; - -webkit-animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; - animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; - -webkit-animation-delay: 1.15s; - animation-delay: 1.15s; -} - -@-webkit-keyframes indeterminate { - 0% { - left: -35%; - right: 100%; - } - 60% { - left: 100%; - right: -90%; - } - 100% { - left: 100%; - right: -90%; - } -} - -@keyframes indeterminate { - 0% { - left: -35%; - right: 100%; - } - 60% { - left: 100%; - right: -90%; - } - 100% { - left: 100%; - right: -90%; - } -} -@-webkit-keyframes indeterminate-short { - 0% { - left: -200%; - right: 100%; - } - 60% { - left: 107%; - right: -8%; - } - 100% { - left: 107%; - right: -8%; - } -} -@keyframes indeterminate-short { - 0% { - left: -200%; - right: 100%; - } - 60% { - left: 107%; - right: -8%; - } - 100% { - left: 107%; - right: -8%; - } -} -/* - @license - Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - Code distributed by Google as part of the polymer project is also - subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ -/**************************/ -/* STYLES FOR THE SPINNER */ -/**************************/ -/* - * Constants: - * STROKEWIDTH = 3px - * ARCSIZE = 270 degrees (amount of circle the arc takes up) - * ARCTIME = 1333ms (time it takes to expand and contract arc) - * ARCSTARTROT = 216 degrees (how much the start location of the arc - * should rotate each time, 216 gives us a - * 5 pointed star shape (it's 360/5 * 3). - * For a 7 pointed star, we might do - * 360/7 * 3 = 154.286) - * CONTAINERWIDTH = 28px - * SHRINK_TIME = 400ms - */ -.preloader-wrapper { - display: inline-block; - position: relative; - width: 50px; - height: 50px; -} -.preloader-wrapper.small { - width: 36px; - height: 36px; -} -.preloader-wrapper.big { - width: 64px; - height: 64px; -} -.preloader-wrapper.active { - /* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */ - -webkit-animation: container-rotate 1568ms linear infinite; - animation: container-rotate 1568ms linear infinite; -} - -@-webkit-keyframes container-rotate { - to { - -webkit-transform: rotate(360deg); - } -} -@keyframes container-rotate { - to { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -.spinner-layer { - position: absolute; - width: 100%; - height: 100%; - opacity: 0; - border-color: var(--md-sys-color-primary); -} - -.spinner-blue, -.spinner-blue-only { - border-color: #4285f4; -} - -.spinner-red, -.spinner-red-only { - border-color: #db4437; -} - -.spinner-yellow, -.spinner-yellow-only { - border-color: #f4b400; -} - -.spinner-green, -.spinner-green-only { - border-color: #0f9d58; -} - -/** - * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee): - * - * iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't - * guarantee that the animation will start _exactly_ after that value. So we avoid using - * animation-delay and instead set custom keyframes for each color (as redundant as it - * seems). - * - * We write out each animation in full (instead of separating animation-name, - * animation-duration, etc.) because under the polyfill, Safari does not recognize those - * specific properties properly, treats them as -webkit-animation, and overrides the - * other animation rules. See https://github.com/Polymer/platform/issues/53. - */ -.active .spinner-layer.spinner-blue { - /* durations: 4 * ARCTIME */ - -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; -} - -.active .spinner-layer.spinner-red { - /* durations: 4 * ARCTIME */ - -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; -} - -.active .spinner-layer.spinner-yellow { - /* durations: 4 * ARCTIME */ - -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; -} - -.active .spinner-layer.spinner-green { - /* durations: 4 * ARCTIME */ - -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; -} - -.active .spinner-layer, -.active .spinner-layer.spinner-blue-only, -.active .spinner-layer.spinner-red-only, -.active .spinner-layer.spinner-yellow-only, -.active .spinner-layer.spinner-green-only { - /* durations: 4 * ARCTIME */ - opacity: 1; - -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; -} - -@-webkit-keyframes fill-unfill-rotate { - 12.5% { - -webkit-transform: rotate(135deg); - } /* 0.5 * ARCSIZE */ - 25% { - -webkit-transform: rotate(270deg); - } /* 1 * ARCSIZE */ - 37.5% { - -webkit-transform: rotate(405deg); - } /* 1.5 * ARCSIZE */ - 50% { - -webkit-transform: rotate(540deg); - } /* 2 * ARCSIZE */ - 62.5% { - -webkit-transform: rotate(675deg); - } /* 2.5 * ARCSIZE */ - 75% { - -webkit-transform: rotate(810deg); - } /* 3 * ARCSIZE */ - 87.5% { - -webkit-transform: rotate(945deg); - } /* 3.5 * ARCSIZE */ - to { - -webkit-transform: rotate(1080deg); - } /* 4 * ARCSIZE */ -} -@keyframes fill-unfill-rotate { - 12.5% { - -webkit-transform: rotate(135deg); - transform: rotate(135deg); - } /* 0.5 * ARCSIZE */ - 25% { - -webkit-transform: rotate(270deg); - transform: rotate(270deg); - } /* 1 * ARCSIZE */ - 37.5% { - -webkit-transform: rotate(405deg); - transform: rotate(405deg); - } /* 1.5 * ARCSIZE */ - 50% { - -webkit-transform: rotate(540deg); - transform: rotate(540deg); - } /* 2 * ARCSIZE */ - 62.5% { - -webkit-transform: rotate(675deg); - transform: rotate(675deg); - } /* 2.5 * ARCSIZE */ - 75% { - -webkit-transform: rotate(810deg); - transform: rotate(810deg); - } /* 3 * ARCSIZE */ - 87.5% { - -webkit-transform: rotate(945deg); - transform: rotate(945deg); - } /* 3.5 * ARCSIZE */ - to { - -webkit-transform: rotate(1080deg); - transform: rotate(1080deg); - } /* 4 * ARCSIZE */ -} -@-webkit-keyframes blue-fade-in-out { - from { - opacity: 1; - } - 25% { - opacity: 1; - } - 26% { - opacity: 0; - } - 89% { - opacity: 0; - } - 90% { - opacity: 1; - } - 100% { - opacity: 1; - } -} -@keyframes blue-fade-in-out { - from { - opacity: 1; - } - 25% { - opacity: 1; - } - 26% { - opacity: 0; - } - 89% { - opacity: 0; - } - 90% { - opacity: 1; - } - 100% { - opacity: 1; - } -} -@-webkit-keyframes red-fade-in-out { - from { - opacity: 0; - } - 15% { - opacity: 0; - } - 25% { - opacity: 1; - } - 50% { - opacity: 1; - } - 51% { - opacity: 0; - } -} -@keyframes red-fade-in-out { - from { - opacity: 0; - } - 15% { - opacity: 0; - } - 25% { - opacity: 1; - } - 50% { - opacity: 1; - } - 51% { - opacity: 0; - } -} -@-webkit-keyframes yellow-fade-in-out { - from { - opacity: 0; - } - 40% { - opacity: 0; - } - 50% { - opacity: 1; - } - 75% { - opacity: 1; - } - 76% { - opacity: 0; - } -} -@keyframes yellow-fade-in-out { - from { - opacity: 0; - } - 40% { - opacity: 0; - } - 50% { - opacity: 1; - } - 75% { - opacity: 1; - } - 76% { - opacity: 0; - } -} -@-webkit-keyframes green-fade-in-out { - from { - opacity: 0; - } - 65% { - opacity: 0; - } - 75% { - opacity: 1; - } - 90% { - opacity: 1; - } - 100% { - opacity: 0; - } -} -@keyframes green-fade-in-out { - from { - opacity: 0; - } - 65% { - opacity: 0; - } - 75% { - opacity: 1; - } - 90% { - opacity: 1; - } - 100% { - opacity: 0; - } -} -/** - * Patch the gap that appear between the two adjacent div.circle-clipper while the - * spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11). - */ -.gap-patch { - position: absolute; - top: 0; - left: 45%; - width: 10%; - height: 100%; - overflow: hidden; - border-color: inherit; -} - -.gap-patch .circle { - width: 1000%; - left: -450%; -} - -.circle-clipper { - display: inline-block; - position: relative; - width: 50%; - height: 100%; - overflow: hidden; - border-color: inherit; -} -.circle-clipper .circle { - width: 200%; - height: 100%; - border-width: 3px; /* STROKEWIDTH */ - border-style: solid; - border-color: inherit; - border-bottom-color: transparent !important; - border-radius: 50%; - -webkit-animation: none; - animation: none; - position: absolute; - top: 0; - right: 0; - bottom: 0; -} -.circle-clipper.left .circle { - left: 0; - border-right-color: transparent !important; - -webkit-transform: rotate(129deg); - transform: rotate(129deg); -} -.circle-clipper.right .circle { - left: -100%; - border-left-color: transparent !important; - -webkit-transform: rotate(-129deg); - transform: rotate(-129deg); -} - -.active .circle-clipper.left .circle { - /* duration: ARCTIME */ - -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; -} - -.active .circle-clipper.right .circle { - /* duration: ARCTIME */ - -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; -} - -@-webkit-keyframes left-spin { - from { - -webkit-transform: rotate(130deg); - } - 50% { - -webkit-transform: rotate(-5deg); - } - to { - -webkit-transform: rotate(130deg); - } -} -@keyframes left-spin { - from { - -webkit-transform: rotate(130deg); - transform: rotate(130deg); - } - 50% { - -webkit-transform: rotate(-5deg); - transform: rotate(-5deg); - } - to { - -webkit-transform: rotate(130deg); - transform: rotate(130deg); - } -} -@-webkit-keyframes right-spin { - from { - -webkit-transform: rotate(-130deg); - } - 50% { - -webkit-transform: rotate(5deg); - } - to { - -webkit-transform: rotate(-130deg); - } -} -@keyframes right-spin { - from { - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); - } - 50% { - -webkit-transform: rotate(5deg); - transform: rotate(5deg); - } - to { - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); - } -} -#spinnerContainer.cooldown { - /* duration: SHRINK_TIME */ - -webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1); - animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1); -} - -@-webkit-keyframes fade-out { - from { - opacity: 1; - } - to { - opacity: 0; - } -} -@keyframes fade-out { - from { - opacity: 1; - } - to { - opacity: 0; - } -} -.slider { - position: relative; - height: 400px; - width: 100%; -} -.slider.fullscreen { - height: 100%; - width: 100%; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; -} -.slider.fullscreen ul.slides { - padding-left: 0; - list-style-type: none; - height: 100%; -} -.slider.fullscreen ul.indicators { - padding-left: 0; - list-style-type: none; - z-index: 2; - bottom: 30px; -} -.slider.fullscreen ul.indicators .indicator-item { - background-color: rgba(255, 255, 255, 0.45); -} -.slider.fullscreen ul.indicators .indicator-item.active { - background-color: var(--md-ref-palette-primary100); -} -.slider .slides { - background-color: var(--md-sys-color-surface); - margin: 0; - height: 400px; - padding-left: 0; - list-style-type: none; -} -.slider .slides li { - padding-left: 0; - list-style-type: none; - opacity: 0; - position: absolute; - top: 0; - left: 0; - z-index: 1; - width: 100%; - height: inherit; - overflow: hidden; -} -.slider .slides li img { - height: 100%; - width: 100%; - background-size: cover; - background-position: center; -} -.slider .slides li .caption { - color: #fff; - position: absolute; - top: 15%; - left: 15%; - width: 70%; - opacity: 0; -} -.slider .slides li .caption p { - color: rgba(255, 255, 255, 0.75); -} -.slider .slides li.active { - z-index: 2; -} -.slider .indicators { - padding-left: 0; - list-style-type: none; - position: absolute; - text-align: center; - left: 0; - right: 0; - bottom: 0; - margin: 0; -} -.slider .indicators .indicator-item { - display: inline-block; - position: relative; - height: 16px; - width: 16px; - margin: 0 12px; -} -.slider .indicators .indicator-item-btn { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - cursor: pointer; - background-color: var(--md-sys-color-shadow-light); - -webkit-transition: background-color 0.3s; - transition: background-color 0.3s; - border-radius: 50%; - border-width: 0; -} -.slider .indicators .indicator-item-btn.active { - background-color: var(--md-sys-color-primary); -} - -.carousel { - --carousel-height: 400px; - overflow: hidden; - position: relative; - width: 100%; - height: var(--carousel-height); - -webkit-perspective: 500px; - perspective: 500px; - -webkit-transform-style: preserve-3d; - transform-style: preserve-3d; - -webkit-transform-origin: 0% 50%; - transform-origin: 0% 50%; -} -.carousel.carousel-slider { - top: 0; - left: 0; -} -.carousel.carousel-slider .carousel-fixed-item { - position: absolute; - left: 0; - right: 0; - bottom: 20px; - z-index: 1; -} -.carousel.carousel-slider .carousel-fixed-item.with-indicators { - bottom: 68px; -} -.carousel.carousel-slider .carousel-item { - width: 100%; - height: 100%; - min-height: var(--carousel-height); - position: absolute; - top: 0; - left: 0; -} -.carousel.carousel-slider .carousel-item h2 { - font-size: 24px; - font-weight: 500; - line-height: 32px; -} -.carousel.carousel-slider .carousel-item p { - font-size: 15px; -} -.carousel .carousel-item { - visibility: hidden; - width: calc(var(--carousel-height) * 0.5); - height: calc(var(--carousel-height) * 0.5); - position: absolute; - top: 0; - left: 0; -} -.carousel .carousel-item > img { - width: 100%; -} -.carousel .indicators { - padding-left: 0; - list-style-type: none; - position: absolute; - text-align: center; - left: 0; - right: 0; - bottom: 0; - margin: 0; -} -.carousel .indicators .indicator-item { - display: inline-block; - position: relative; - cursor: pointer; - height: 8px; - width: 8px; - margin: 24px 4px; - background-color: rgba(255, 255, 255, 0.45); - -webkit-transition: background-color 0.3s; - transition: background-color 0.3s; - border-radius: 50%; -} -.carousel .indicators .indicator-item.active { - background-color: var(--md-ref-palette-primary100); -} -.carousel.scrolling .carousel-item .materialboxed, -.carousel .carousel-item:not(.active) .materialboxed { - pointer-events: none; -} - -.datepicker-container { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - max-width: 325px; - padding: 0; - background-color: var(--md-sys-color-inverse-on-surface); -} - -.datepicker-controls { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - width: 280px; - margin: 0 auto; -} -.datepicker-controls .selects-container { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} -.datepicker-controls .select-wrapper input { - height: 49px; - margin: 4px 0 0 0; - border-bottom: none; - border-radius: 4px; - text-align: center; -} -.datepicker-controls .select-wrapper input:focus { - color: var(--md-sys-color-primary); - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%); -} -.datepicker-controls .select-wrapper input::-moz-selection { - background-color: transparent; -} -.datepicker-controls .select-wrapper input::selection { - background-color: transparent; -} -.datepicker-controls .select-wrapper .caret { - display: none; -} -.datepicker-controls .select-dropdown { - padding: 0; - vertical-align: middle; -} -.datepicker-controls .select-year input, -.datepicker-controls .select-month input { - background-color: transparent; -} -.datepicker-controls .select-year input { - width: 50px; -} -.datepicker-controls .select-month input { - width: 80px; -} -.datepicker-controls .month-prev, -.datepicker-controls .month-next { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 49px; - border-radius: var(--btn-border-radius); - padding-left: var(--btn-padding); - padding-right: var(--btn-padding); - font-size: var(--btn-font-size); - font-weight: 500; - text-decoration: none; - display: inline-flex; - align-items: center; - border: none; - cursor: pointer; - -webkit-tap-highlight-color: transparent; - white-space: nowrap; - outline: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-transition: background-color 0.2s ease-out; - transition: background-color 0.2s ease-out; -} -.datepicker-controls .month-prev:focus, -.datepicker-controls .month-next:focus { - background-color: var(--md-sys-color-primary-container); -} -.datepicker-controls .month-prev:focus, -.datepicker-controls .month-next:focus { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%); -} -.datepicker-controls .month-prev > svg, -.datepicker-controls .month-next > svg { - fill: var(--md-sys-color-on-surface-variant); -} - -.month-prev, .month-next { - height: 49px; - margin-top: 4px; - cursor: pointer; - background-color: transparent; - border: none; -} - -/* Date Display */ -.datepicker-date-display { - -webkit-box-flex: 1; - -webkit-flex: 1 auto; - -ms-flex: 1 auto; - flex: 1 auto; - padding: 20px 22px; - border-bottom: 1px solid var(--md-sys-color-surface-variant-light); - font-weight: 500; -} -.datepicker-date-display .year-text { - display: block; - font-size: 1.5rem; - line-height: 25px; - color: var(--md-sys-color-on-primary); -} -.datepicker-date-display .date-text { - display: block; - font-size: 2.8rem; - line-height: 47px; - font-weight: 500; -} -.daterange .datepicker-date-display .date-text { - font-size: 1.8rem; -} - -/* Calendar */ -.datepicker-calendar-container { - -webkit-box-flex: 2.5; - -webkit-flex: 2.5 auto; - -ms-flex: 2.5 auto; - flex: 2.5 auto; -} - -.datepicker-table { - width: 280px; - font-size: 1rem; - margin: 0 auto; -} -.datepicker-table thead { - border-bottom: none; -} -.datepicker-table th { - padding: 10px 5px; - text-align: center; -} -.datepicker-table tr { - border: none; -} -.datepicker-table abbr { - text-decoration: none; - color: var(--md-sys-color-on-surface-variant); -} -.datepicker-table .datepicker-day { - padding: 0; - color: var(--md-sys-color-on-background); -} -.datepicker-table .datepicker-day.is-today { - color: var(--md-sys-color-primary); -} -.datepicker-table .datepicker-day { - /*&.is-selected button { - background-color: var(--md-sys-color-primary); - color: var(--md-sys-color-on-primary); - }*/ -} - -.datepicker-day.is-daterange-start, -.datepicker-day.is-daterange-end, -.datepicker-day.is-daterange { - position: relative; -} -.datepicker-day.is-daterange-start:before, -.datepicker-day.is-daterange-end:before, -.datepicker-day.is-daterange:before { - position: absolute; - top: 5px; - width: 100%; - height: 34px; - content: ""; - background-color: var(--md-sys-color-primary-container); - z-index: 0; -} - -.datepicker-day.is-daterange-start:before, -.datepicker-day.is-daterange-end:before { - width: 50%; -} - -.datepicker-day.is-daterange-start:before { - left: 50%; -} - -.datepicker-day.is-daterange .datepicker-day-button:before { - background-color: var(--md-sys-color-primary-container); -} - -.datepicker-day-button { - background-color: transparent; - border: none; - line-height: 34px; - display: block; - width: 34px; - border-radius: 50%; - margin: 5px; - padding: 0 5px; - cursor: pointer; - color: inherit; - position: relative; - z-index: 1; -} -.datepicker-day-button:hover { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%); -} -.datepicker-day-button:focus { - border-color: var(--md-sys-color-primary); -} -.is-selected .datepicker-day-button { - background-color: var(--md-sys-color-primary); - color: var(--md-sys-color-on-primary); -} -.is-selected .datepicker-day-button:focus { - background-color: var(--md-sys-color-surface-variant); - color: var(--md-sys-color-primary); -} -.datepicker-day-button.is-outside-current-month button, .datepicker-day-button.is-disabled button { - color: var(--md-sys-color-on-surface); - pointer-events: none; -} - -/* Footer */ -.datepicker-footer { - width: 280px; - margin: 0 auto; - padding-bottom: 5px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.datepicker-cancel, -.datepicker-clear, -.datepicker-today, -.datepicker-done { - color: var(--md-sys-color-primary); - padding: 0 1rem; -} - -.datepicker-clear { - color: var(--md-sys-color-error); -} - -/* Display modes */ -.datepicker-modal { - max-width: calc(325px + var(--modal-padding) * 2); - max-height: none; - background-color: var(--md-sys-color-inverse-on-surface); -} - -.timepicker-container { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - max-width: 325px; - padding: 0; - background-color: var(--md-sys-color-inverse-on-surface); -} - -.text-primary { - color: var(--md-sys-color-on-primary); -} - -/* Clock Digital Display */ -.timepicker-digital-display { - width: auto; - -webkit-box-flex: 1; - -webkit-flex: 1 auto; - -ms-flex: 1 auto; - flex: 1 auto; - padding: 2rem 0.71rem 0.67rem 0.71rem; - font-weight: 300; -} - -.timepicker-text-container { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 4rem; - text-align: left; - color: var(--font-on-primary-color-medium); - font-weight: 400; - /*position: relative;*/ - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - padding: 1rem 1rem 1.3rem 1rem; -} -.timepicker-text-container input[type=text] { - height: 4rem; - color: var(--md-sys-color-secondary); - border-bottom: 0px; - font-size: 4rem; - direction: ltr; -} - -.timepicker-display-column { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.timepicker-display-digital-clock { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; -} - -.timepicker-input-hours-wrapper, -.timepicker-input-minutes-wrapper { - width: 6.85rem; - height: 5.75rem; -} - -.timepicker-input-hours, -.timepicker-input-minutes, -.timepicker-span-am-pm div { - cursor: pointer; -} - -input[type=text].timepicker-input-hours, -input[type=text].timepicker-input-minutes { - height: 100%; - padding: 1.33rem 0.8rem; - border: 0; - text-align: center; - color: var(--md-sys-color-on-background); - background-color: var(--md-sys-color-surface-variant); -} -input[type=text].timepicker-input-hours:focus, -input[type=text].timepicker-input-minutes:focus { - background-color: var(--md-sys-color-primary-container); -} - -.timepicker-input-divider-wrapper { - width: 1.6rem; - text-align: center; -} - -/*input[type=text].text-primary { - color: var(--md-sys-color-on-background); -}*/ -.timepicker-display-am-pm { - font-size: 1.3rem; - /*position: absolute; - top: 1rem; - right: 1rem;*/ - font-weight: 400; -} - -.timepicker-span-am-pm { - height: 5.75rem; - max-width: 3.5rem; -} - -.timepicker-container .am-btn, -.timepicker-container .pm-btn { - width: 3.6rem; - height: 50%; - padding-left: calc(var(--btn-padding) / 1.8); - padding-right: calc(var(--btn-padding) / 1.8); - line-height: 2rem; - vertical-align: middle; - text-align: center; - border: 1px solid var(--md-sys-color-outline); -} - -.timepicker-container .am-btn { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} - -.timepicker-container .pm-btn { - border-top: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -/* Analog Clock Display */ -.timepicker-analog-display { - -webkit-box-flex: 2.5; - -webkit-flex: 2.5 auto; - -ms-flex: 2.5 auto; - flex: 2.5 auto; - padding: 0.67rem; -} - -.timepicker-plate { - background-color: var(--md-sys-color-surface-variant); - border-radius: 50%; - width: 260px; - height: 260px; - overflow: visible; - position: relative; - margin: 0 1.6rem 1.6rem 1.6rem; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.timepicker-canvas, -.timepicker-dial { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; -} - -.timepicker-minutes { - visibility: hidden; -} - -.timepicker-tick { - border-radius: 50%; - color: var(--md-sys-color-on-background); - line-height: 40px; - text-align: center; - width: 40px; - height: 40px; - position: absolute; - cursor: pointer; - font-size: 15px; -} - -.timepicker-tick.active, -.timepicker-tick:hover { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%); -} - -.timepicker-dial { - -webkit-transition: opacity 350ms, -webkit-transform 350ms; - transition: opacity 350ms, -webkit-transform 350ms; - transition: transform 350ms, opacity 350ms; - transition: transform 350ms, opacity 350ms, -webkit-transform 350ms; -} - -.timepicker-dial-out { - opacity: 0; -} -.timepicker-dial-out.timepicker-hours { - -webkit-transform: scale(1.1, 1.1); - transform: scale(1.1, 1.1); -} -.timepicker-dial-out.timepicker-minutes { - -webkit-transform: scale(0.8, 0.8); - transform: scale(0.8, 0.8); -} - -.timepicker-canvas { - -webkit-transition: opacity 175ms; - transition: opacity 175ms; -} -.timepicker-canvas line { - stroke: var(--md-sys-color-primary); - stroke-width: 4; - stroke-linecap: round; -} - -.timepicker-canvas-out { - opacity: 0.25; -} - -.timepicker-canvas-bearing { - stroke: none; - fill: var(--md-sys-color-primary); -} - -.timepicker-canvas-bg { - stroke: none; - fill: var(--md-sys-color-primary); -} - -/* Footer */ -.timepicker-footer { - margin: 0 auto; - padding: 5px 1rem; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.timepicker-clear { - color: var(--md-sys-color-error); -} - -.timepicker-close { - color: var(--md-sys-color-primary); -} - -.timepicker-clear, -.timepicker-close { - padding: 0 20px; -} - -/* Display modes */ -.timepicker-modal { - max-width: 326px; - max-height: none; - background-color: var(--md-sys-color-inverse-on-surface); - overflow-x: hidden; -} -.timepicker-modal .timepicker-container { - margin-left: calc(-1 * var(--modal-padding)); - margin-right: calc(-1 * var(--modal-padding)); -} -.timepicker-modal .modal-header + .modal-content .timepicker-digital-display { - padding-top: 0; -} -.timepicker-modal .modal-header + .modal-content .timepicker-text-container { - padding-top: 4px; -} -.timepicker-modal .timepicker-analog-display { - padding-bottom: 0; -} -.timepicker-modal .timepicker-plate { - margin-bottom: 0; -} - -/* Media Queries */ -@media only screen and (min-width : 993px) { - .timepicker-container { - width: auto; - max-width: 620px; - } - .timepicker-container { - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - } - .timepicker-digital-display { - padding: 0.67rem; - } - .timepicker-text-container { - /*top: 31%;*/ - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - margin-top: 4.8rem; - text-align: center; - } - .timepicker-display-column { - padding: 0 3%; - } - .timepicker-display-am-pm { - margin-top: 1.1rem; - } - .timepicker-span-am-pm { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - max-width: unset; - /*width: 100%; - padding: 0 4%; - flex-wrap: wrap; - flex-direction: row; - display: flex;*/ - } - .timepicker-container .am-btn, - .timepicker-container .pm-btn { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; - /*width: auto;*/ - padding-left: calc(var(--btn-padding) / 0.565); - padding-right: calc(var(--btn-padding) / 0.565); - border-radius: var(--btn-border-radius); - border: 1px solid var(--md-sys-color-outline); - } - .timepicker-container .am-btn { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - .timepicker-container .pm-btn { - border-left: 0; - border-bottom-left-radius: 0; - border-top-left-radius: 0; - } - .timepicker-plate { - margin-top: 1.6rem; - } - /* Display modes */ - .timepicker-modal { - width: 65%; - max-width: 605px; - } - .timepicker-modal .modal-header + .modal-content .timepicker-digital-display, - .timepicker-modal .modal-header + .modal-content .timepicker-analog-display { - padding-top: 0; - } - .timepicker-modal .modal-header + .modal-content .timepicker-text-container { - margin-top: 2.4rem; - } - .timepicker-modal .modal-header + .modal-content .timepicker-plate { - margin-top: 4px; - margin-bottom: 0; - } - .timepicker-modal .timepicker-digital-display, - .timepicker-modal .timepicker-analog-display { - padding-bottom: 0; - } - .timepicker-modal .timepicker-plate { - margin-bottom: 0; - } -} -.breadcrumb-wrapper { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; -} - -.breadcrumb { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; -} -.breadcrumb i, -.breadcrumb i.material-icons, .breadcrumb i.material-symbols-outlined, -.breadcrumb i.material-symbols-rounded, .breadcrumb i.material-symbols-sharp, .breadcrumb:before { - font-weight: normal; - font-style: normal; - font-size: 24px; -} -.breadcrumb:before { - content: "\e5cc"; - font-family: "Material Symbols Outlined", "Material Symbols Rounded", "Material Symbols Sharp", "Material Icons"; -} -.breadcrumb:first-child:before { - visibility: hidden; -} - -.pagination li { - display: inline-block; - vertical-align: top; -} -.pagination li a { - height: 2rem; - border-radius: var(--btn-border-radius); - padding-left: 0.66rem; - padding-right: 0.66rem; - font-size: 1.2rem; - font-weight: 500; - text-decoration: none; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - border: none; - cursor: pointer; - -webkit-tap-highlight-color: transparent; - white-space: nowrap; - outline: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-transition: background-color 0.2s ease-out; - transition: background-color 0.2s ease-out; -} -.pagination li a:focus { - background-color: var(--md-sys-color-primary-container); -} -.pagination li.active a { - color: var(--md-sys-color-on-primary); - background-color: var(--md-sys-color-primary); -} -.pagination li.active a:hover, .pagination li.active a:focus { - color: var(--md-sys-color-on-primary); -} -.pagination li.active a:hover { - background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 16%); -} -.pagination li.active a:focus { - background-color: color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 20%); -} -.pagination li.active a:focus-visible { - outline: 3px solid var(--md-sys-color-secondary); - outline-offset: 2px; -} -.pagination li.disabled a { - color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - background-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%); - pointer-events: none; - -webkit-box-shadow: none; - box-shadow: none; - cursor: default; -} -.pagination li i { - font-size: 2rem; -} -.pagination li.pages ul li { - display: inline-block; - float: none; -} - -@media only screen and (max-width : 992.99px) { - .pagination { - width: 100%; - } - .pagination li.prev, - .pagination li.next { - width: 10%; - } - .pagination li.pages { - width: 80%; - overflow: hidden; - white-space: nowrap; - } -} -[type=radio]:not(:checked), -[type=radio]:checked { - position: absolute; - opacity: 0; - pointer-events: none; -} - -[type=radio]:not(:checked) + span, -[type=radio]:checked + span { - position: relative; - padding-left: 35px; - cursor: pointer; - display: inline-block; - height: 25px; - line-height: 25px; - font-size: 1rem; - -webkit-transition: 0.28s ease; - transition: 0.28s ease; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -[type=radio] + span:before, -[type=radio] + span:after { - content: ""; - position: absolute; - left: 0; - top: 0; - margin: 4px; - width: 16px; - height: 16px; - z-index: 0; - -webkit-transition: 0.28s ease; - transition: 0.28s ease; -} - -/* Unchecked styles */ -[type=radio]:not(:checked) + span:before, -[type=radio]:not(:checked) + span:after, -[type=radio]:checked + span:before, -[type=radio]:checked + span:after, -[type=radio].with-gap:checked + span:before, -[type=radio].with-gap:checked + span:after { - border-radius: 50%; -} - -[type=radio]:not(:checked) + span:before, -[type=radio]:not(:checked) + span:after { - border: 2px solid var(--md-sys-color-on-surface-variant); -} - -[type=radio]:not(:checked) + span:after { - -webkit-transform: scale(0); - transform: scale(0); -} - -/* Checked styles */ -[type=radio]:checked + span:before { - border: 2px solid transparent; -} - -[type=radio]:checked + span:after, -[type=radio].with-gap:checked + span:before, -[type=radio].with-gap:checked + span:after { - border: 2px solid var(--md-sys-color-primary); -} - -[type=radio]:checked + span:after, -[type=radio].with-gap:checked + span:after { - background-color: var(--md-sys-color-primary); -} - -[type=radio]:checked + span:after { - -webkit-transform: scale(1.02); - transform: scale(1.02); -} - -/* Radio With gap */ -[type=radio].with-gap:checked + span:after { - -webkit-transform: scale(0.5); - transform: scale(0.5); -} - -/* Focused styles */ -[type=radio].tabbed:focus + span:before { - -webkit-box-shadow: 0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); - box-shadow: 0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); -} - -/* Disabled Radio With gap */ -[type=radio].with-gap:disabled:checked + span:before { - border: 2px solid color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} - -[type=radio].with-gap:disabled:checked + span:after { - border: none; - background-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} - -/* Disabled style */ -[type=radio]:disabled:not(:checked) + span:before, -[type=radio]:disabled:checked + span:before { - background-color: transparent; - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} - -[type=radio]:disabled + span { - color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} - -[type=radio]:disabled:not(:checked) + span:before { - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} - -[type=radio]:disabled:checked + span:after { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} - -/* Checkboxes */ -:root { - --checkbox-size: 18px; - --checkbox-shape: 2px; -} - -input[type=checkbox] { - /* Add if not using autoprefixer */ - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - /* For iOS < 15 to remove gradient background */ - margin: 0; - position: relative; - cursor: pointer; -} - -input[type=checkbox]:focus { - outline: 3px solid var(--md-sys-color-secondary); - border-radius: 50%; - outline-offset: 0.5rem; -} - -input[type=checkbox]:before { - opacity: 1; - position: absolute; - display: block; - width: var(--checkbox-size); - height: var(--checkbox-size); - border: 2px solid var(--md-sys-color-on-surface-variant); - border-radius: var(--checkbox-shape); - content: ""; -} - -input[type=checkbox]:after { - position: relative; - display: block; - width: var(--checkbox-size); - height: var(--checkbox-size); - content: ""; - border-radius: var(--checkbox-shape); - background-repeat: no-repeat; - background-position: center; -} - -input[type=checkbox]:checked:after { - background-color: var(--md-sys-color-primary); - -webkit-clip-path: polygon(0 48%, 0 0, 56% 0, 74% 17%, 40% 64%, 23% 50%, 14% 61%, 42% 82%, 81% 31%, 32% 0, 100% 0, 100% 100%, 0 100%, 0 49%); - clip-path: polygon(0 48%, 0 0, 56% 0, 74% 17%, 40% 64%, 23% 50%, 14% 61%, 42% 82%, 81% 31%, 32% 0, 100% 0, 100% 100%, 0 100%, 0 49%); -} - -[type=checkbox]:indeterminate:after { - background-color: var(--md-sys-color-primary); - -webkit-clip-path: polygon(0% 0%, 0% 100%, 18% 100%, 16% 43%, 83% 42%, 83% 63%, 16% 63%, 16% 100%, 100% 100%, 100% 0%); - clip-path: polygon(0% 0%, 0% 100%, 18% 100%, 16% 43%, 83% 42%, 83% 63%, 16% 63%, 16% 100%, 100% 100%, 100% 0%); -} - -input[type=checkbox]:disabled:before { - -webkit-filter: opacity(0.2); - filter: opacity(0.2); -} - -input[type=checkbox]:disabled:after { - -webkit-filter: opacity(0.2); - filter: opacity(0.2); -} - -input[type=checkbox]:not(:disabled):checked:hover:after { - background-color: var(--md-sys-color-primary); -} - -input[type=checkbox]:not(:disabled):hover:after { - border-color: #85A9BB #92C2DA #92C2DA #85A9BB; -} - -input[type=checkbox]:not(:disabled):hover:before { - border-color: #3D7591; -} - -/* -// Checkbox Styles -[type="checkbox"] { - // Text Label Style - + span:not(.lever) { - position: relative; - cursor: pointer; - display: inline-block; - height: var(--checkbox-size); - line-height: var(--checkbox-size); - padding-left: var(--checkbox-size); - // background-color: red; - font-size: 1rem; - user-select: none; - } - - // checkbox aspect - + span:not(.lever):before, - &:not(.filled-in) + span:not(.lever):after { - content: ''; - position: absolute; - top: 0; - left: 0; - width: var(--checkbox-size); - height: var(--checkbox-size); - z-index: 0; - border: 2px solid var(--md-sys-color-on-surface-variant); - border-radius: 1px; - transition: .2s; - } - - &:not(.filled-in) + span:not(.lever):after { - border: 0; - transform: scale(0); - } - - &:not(:checked):disabled + span:not(.lever):before { - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - } - - &:disabled + span:not(.lever) { - color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - } - - // Focused styles - &.tabbed:focus + span:not(.lever):after { - transform: scale(1); - border: 0; - border-radius: 50%; - box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.12); - background-color: rgba(0, 0, 0, 0.12); - } -} - -[type="checkbox"]:checked { - + span:not(.lever):before { - top: -4px; - left: -5px; - width: 12px; - height: 22px; - border-top: 2px solid transparent; - border-left: 2px solid transparent; - border-right: 2px solid var(--md-sys-color-primary); - border-bottom: 2px solid var(--md-sys-color-primary); - transform: rotate(40deg); - backface-visibility: hidden; - transform-origin: 100% 100%; - } - - &:disabled + span:before { - border-right: 2px solid color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - border-bottom: 2px solid color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - } -} - -// Indeterminate checkbox -[type="checkbox"]:indeterminate { - + span:not(.lever):before { - top: -11px; - left: -12px; - width: 10px; - height: 22px; - border-top: none; - border-left: none; - border-right: 2px solid var(--md-sys-color-primary); - border-bottom: none; - transform: rotate(90deg); - backface-visibility: hidden; - transform-origin: 100% 100%; - } - - // Disabled indeterminate - &:disabled + span:not(.lever):before { - border-right: 2px solid color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - background-color: transparent; - } -} - -// Filled in Style -[type="checkbox"].filled-in { - // General - + span:not(.lever):after { - border-radius: 2px; - } - - + span:not(.lever):before, - + span:not(.lever):after { - content: ''; - left: 0; - position: absolute; - // .1s delay is for check animation - transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s; - z-index: 1; - } - - // Unchecked style - &:not(:checked) + span:not(.lever):before { - width: 0; - height: 0; - border: 3px solid transparent; - left: 6px; - top: 10px; - transform: rotateZ(37deg); - transform-origin: 100% 100%; - } - - &:not(:checked) + span:not(.lever):after { - height: 20px; - width: 20px; - background-color: transparent; - border: 2px solid var(--md-sys-color-on-surface-variant); - top: 0px; - z-index: 0; - } - - // Checked style - &:checked { - + span:not(.lever):before { - top: 0; - left: 1px; - width: 8px; - height: 13px; - border-top: 2px solid transparent; - border-left: 2px solid transparent; - border-right: 2px solid var(--md-sys-color-on-primary); - border-bottom: 2px solid var(--md-sys-color-on-primary); - transform: rotateZ(37deg); - transform-origin: 100% 100%; - } - - + span:not(.lever):after { - top: 0; - width: 20px; - height: 20px; - border: 2px solid var(--md-sys-color-primary); - background-color: var(--md-sys-color-primary); - z-index: 0; - } - } - - // Focused styles - &.tabbed:focus + span:not(.lever):after { - border-radius: 2px; - border-color: var(--md-sys-color-on-surface-variant)r; - background-color: rgba(0, 0, 0, 0.12); - } - - &.tabbed:checked:focus + span:not(.lever):after { - border-radius: 2px; - background-color: var(--md-sys-color-primary); - border-color: var(--md-sys-color-primary); - } - - // Disabled style - &:disabled:not(:checked) + span:not(.lever):before { - background-color: transparent; - border: 2px solid transparent; - } - - &:disabled:not(:checked) + span:not(.lever):after { - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - } - - &:disabled:checked + span:not(.lever):before { - background-color: transparent; - } - - &:disabled:checked + span:not(.lever):after { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - border: none; - } -} -*/ -.switch { - --track-height: 32px; - --track-width: 52px; - --border-width: 2px; - --size-off: 16px; - --size-on: 24px; - --icon-size: 16px; - --gap-on: calc(((var(--track-height) - var(--size-on)) / 2) - var(--border-width)); - --gap-off: calc(((var(--track-height) - var(--size-off)) / 2) - var(--border-width)); -} - -.switch, -.switch * { - -webkit-tap-highlight-color: transparent; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.switch label { - cursor: pointer; -} - -.switch label input[type=checkbox] { - opacity: 0; - width: 0; - height: 0; -} -.switch label input[type=checkbox]:checked + .lever { - background-color: var(--md-sys-color-primary); - border-color: var(--md-sys-color-primary); -} -.switch label input[type=checkbox]:checked + .lever:before, .switch label input[type=checkbox]:checked + .lever:after { - top: var(--gap-on); - left: calc(var(--track-width) - var(--size-on) - var(--gap-on) - 2 * var(--border-width)); - width: var(--size-on); - height: var(--size-on); -} -.switch label input[type=checkbox]:checked + .lever:after { - background-color: var(--md-sys-color-surface); -} - -.switch label .lever { - content: ""; - display: inline-block; - position: relative; - width: var(--track-width); - height: var(--track-height); - border-style: solid; - border-width: 2px; - border-color: var(--md-sys-color-outline); - background-color: var(--md-sys-color-surface-variant); - border-radius: 15px; - margin-right: 10px; - -webkit-transition: background 0.3s ease; - transition: background 0.3s ease; - vertical-align: middle; - margin: 0 16px; -} -.switch label .lever:before, .switch label .lever:after { - content: ""; - position: absolute; - display: inline-block; - width: var(--size-off); - height: var(--size-off); - border-radius: 50%; - left: var(--gap-off); - top: var(--gap-off); - -webkit-transition: left 0.3s ease, background 0.3s ease, -webkit-box-shadow 0.1s ease, -webkit-transform 0.1s ease; - transition: left 0.3s ease, background 0.3s ease, -webkit-box-shadow 0.1s ease, -webkit-transform 0.1s ease; - transition: left 0.3s ease, background 0.3s ease, box-shadow 0.1s ease, transform 0.1s ease; - transition: left 0.3s ease, background 0.3s ease, box-shadow 0.1s ease, transform 0.1s ease, -webkit-box-shadow 0.1s ease, -webkit-transform 0.1s ease; -} -.switch label .lever:after { - background-color: var(--md-sys-color-outline); - height: var(--size-off); - width: var(--size-off); -} - -input[type=checkbox]:not(:disabled) ~ .lever:active:before, -input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::before, -input[type=checkbox]:not(:disabled) ~ .lever:hover::before { - -webkit-transform: scale(2.4); - transform: scale(2.4); -} - -input[type=checkbox]:checked:not(:disabled) ~ .lever:hover::before { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%); -} - -input[type=checkbox]:checked:not(:disabled) ~ .lever:active::before, -input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::before { - background-color: color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); -} - -input[type=checkbox]:not(:disabled) ~ .lever:hover::before { - background-color: rgba(0, 0, 0, 0.04); -} - -input[type=checkbox]:not(:disabled) ~ .lever:active:before, -input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::before { - background-color: rgba(0, 0, 0, 0.12); -} - -.switch input[type=checkbox][disabled] + .lever { - cursor: default; - opacity: 0.5; -} - -.range-field { - position: relative; -} - -input[type=range], -input[type=range] + .thumb { - cursor: pointer; -} - -input[type=range] { - position: relative; - background: linear-gradient(var(--md-sys-color-outline-variant), var(--md-sys-color-outline-variant)); - border: none; - outline: none; - width: 100%; - margin: 15px 0; - padding: 0; - height: 3px; -} -input[type=range]:focus { - outline: none; -} - -input[type=range] + .thumb { - position: absolute; - top: 10px; - left: 0; - border: none; - height: 0; - width: 0; - border-radius: 50%; - background-color: var(--md-sys-color-primary); - margin-left: 7px; - -webkit-transform-origin: 50% 50%; - transform-origin: 50% 50%; - -webkit-transform: rotate(-45deg); - transform: rotate(-45deg); -} -input[type=range] + .thumb .value { - display: block; - width: 30px; - text-align: center; - color: var(--md-sys-color-primary); - font-size: 0; - -webkit-transform: rotate(45deg); - transform: rotate(45deg); -} -input[type=range] + .thumb.active { - border-radius: 50% 50% 50% 0; -} -input[type=range] + .thumb.active .value { - color: var(--md-sys-color-on-primary); - margin-left: -1px; - margin-top: 8px; - font-size: 10px; -} - -input[type=range] { - -moz-appearance: none; - appearance: none; - -webkit-appearance: none; -} - -input[type=range]::-webkit-slider-runnable-track { - height: 3px; - background-color: var(--md-sys-color-surface-variant); - border: none; -} - -input[type=range]::-webkit-slider-thumb { - border: none; - height: 14px; - width: 14px; - border-radius: 50%; - background: var(--md-sys-color-primary); - -webkit-transition: -webkit-box-shadow 0.3s; - transition: -webkit-box-shadow 0.3s; - transition: box-shadow 0.3s; - transition: box-shadow 0.3s, -webkit-box-shadow 0.3s; - -webkit-appearance: none; - background-color: var(--md-sys-color-primary); - -webkit-transform-origin: 50% 50%; - transform-origin: 50% 50%; - margin: -5px 0 0 0; -} - -.keyboard-focused input[type=range]:focus:not(.active)::-webkit-slider-thumb { - -webkit-box-shadow: 0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); - box-shadow: 0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); -} - -input[type=range] { - /*required for proper track sizing in FF*/ -} - -input[type=range]::-moz-range-track { - height: 3px; - background-color: var(--md-sys-color-surface-variant); - border: none; -} - -input[type=range]::-moz-focus-inner { - border: 0; -} - -input[type=range]::-moz-range-thumb { - border: none; - height: 14px; - width: 14px; - border-radius: 50%; - background: var(--md-sys-color-primary); - -moz-transition: box-shadow 0.3s; - transition: box-shadow 0.3s; - margin-top: -5px; -} - -input[type=range]:-moz-focusring { - outline: 1px solid #fff; - outline-offset: -1px; -} - -.keyboard-focused input[type=range]:focus:not(.active)::-moz-range-thumb { - box-shadow: 0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); -} - -input[type=range]::-ms-track { - height: 3px; - background: transparent; - border-color: transparent; - border-width: 6px 0; - /*remove default tick marks*/ - color: transparent; -} - -input[type=range]::-ms-fill-lower, -input[type=range]::-moz-range-progress { - background: var(--md-sys-color-primary); -} - -input[type=range]::-ms-fill-upper, -input[type=range]::-moz-range-track { - background: var(--md-sys-color-shadow-light); -} - -input[type=range]::-ms-thumb { - border: none; - height: 14px; - width: 14px; - border-radius: 50%; - background: var(--md-sys-color-primary); - -ms-transition: box-shadow 0.3s; - transition: box-shadow 0.3s; -} - -.keyboard-focused input[type=range]:focus:not(.active)::-ms-thumb { - box-shadow: 0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%); -} - -/* Style Placeholders */ -::-webkit-input-placeholder { - color: var(--md-sys-color-on-surface-variant); -} -::-moz-placeholder { - color: var(--md-sys-color-on-surface-variant); -} -:-ms-input-placeholder { - color: var(--md-sys-color-on-surface-variant); -} -::-ms-input-placeholder { - color: var(--md-sys-color-on-surface-variant); -} -::placeholder { - color: var(--md-sys-color-on-surface-variant); -} - -/* Text inputs */ -.input-field input.invalid, .input-field textarea.invalid { - border-bottom: 2px solid var(--md-sys-color-error); - -webkit-box-shadow: 0 1px 0 0 var(--md-sys-color-error); - box-shadow: 0 1px 0 0 var(--md-sys-color-error); -} - -.input-field input.invalid ~ .supporting-text[data-error] > span, .input-field textarea.invalid ~ .supporting-text[data-error] > span { - display: none; -} - -.input-field input.invalid ~ .supporting-text:after, .input-field textarea.invalid ~ .supporting-text:after { - content: attr(data-error); - color: var(--md-sys-color-error); -} - -.input-field { - --input-color: var(--md-sys-color-primary); - position: relative; - clear: both; -} -.input-field input, .input-field textarea { - -webkit-box-sizing: border-box; - box-sizing: border-box; /* https://stackoverflow.com/questions/1377719/padding-within-inputs-breaks-width-100*/ - padding: 0 16px; - padding-top: 20px; - border: none; - border-radius: 4px; - border-bottom: 1px solid var(--md-sys-color-on-surface-variant); - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.input-field input:focus:not([readonly]), .input-field textarea:focus:not([readonly]) { - border-bottom: 2px solid var(--input-color); - padding-top: 21px; -} -.input-field input:disabled, .input-field input[readonly=readonly], .input-field textarea:disabled, .input-field textarea[readonly=readonly] { - color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%); - background-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 4%); -} -.input-field input:focus:not([readonly]) + label, .input-field textarea:focus:not([readonly]) + label { - color: var(--input-color); -} -.input-field input:not(:-moz-placeholder) + label, .input-field textarea:not(:-moz-placeholder) + label { - transform: scale(0.75); - top: 8px; -} -.input-field input:not(:-ms-input-placeholder) + label, .input-field textarea:not(:-ms-input-placeholder) + label { - transform: scale(0.75); - top: 8px; -} -.input-field input:focus:not([readonly]) + label, .input-field input:not([placeholder=" "]) + label, .input-field input:not(:placeholder-shown) + label, .input-field textarea:focus:not([readonly]) + label, .input-field textarea:not([placeholder=" "]) + label, .input-field textarea:not(:placeholder-shown) + label { - -webkit-transform: scale(0.75); - transform: scale(0.75); - top: 8px; -} -.input-field input:disabled + label, .input-field input[readonly=readonly] + label, .input-field textarea:disabled + label, .input-field textarea[readonly=readonly] + label { - color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); -} -.input-field input.invalid ~ label, .input-field input:focus.invalid ~ label, .input-field textarea.invalid ~ label, .input-field textarea:focus.invalid ~ label { - color: var(--md-sys-color-error); -} -.input-field input::-webkit-input-placeholder { - -webkit-user-select: none; - user-select: none; -} -.input-field input::-moz-placeholder { - -moz-user-select: none; - user-select: none; -} -.input-field input:-ms-input-placeholder { - -ms-user-select: none; - user-select: none; -} -.input-field input::-ms-input-placeholder { - -ms-user-select: none; - user-select: none; -} -.input-field input::placeholder { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.input-field > label { - color: var(--md-sys-color-on-surface-variant); - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - font-size: 16px; - position: absolute; - left: 16px; - top: 16px; - cursor: text; - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-transition: left 0.2s ease-out, top 0.2s ease-out, -webkit-transform 0.2s ease-out; - transition: left 0.2s ease-out, top 0.2s ease-out, -webkit-transform 0.2s ease-out; - transition: left 0.2s ease-out, top 0.2s ease-out, transform 0.2s ease-out; - transition: left 0.2s ease-out, top 0.2s ease-out, transform 0.2s ease-out, -webkit-transform 0.2s ease-out; -} -.input-field .supporting-text { - color: var(--md-sys-color-on-surface-variant); - font-size: 12px; - padding: 0 16px; - margin-top: 4px; -} -.input-field .character-counter { - color: var(--md-sys-color-on-surface-variant); - font-size: 12px; - float: right; - padding: 0 16px; - margin-top: 4px; -} -.input-field .prefix { - position: absolute; - left: 12px; - top: 16px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; -} -.input-field .suffix { - position: absolute; - right: 12px; - top: 16px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.input-field .prefix ~ input, .input-field .prefix ~ textarea { - padding-left: 52px; -} -.input-field .suffix ~ input, .input-field .suffix ~ textarea { - padding-right: 52px; -} -.input-field .prefix ~ label { - left: 52px; -} -.input-field.outlined input, .input-field.outlined textarea { - padding-top: 0; - background-color: transparent; - border: 1px solid var(--md-sys-color-on-surface-variant); - border-radius: 4px; -} -.input-field.outlined input:focus:not([readonly]), .input-field.outlined textarea:focus:not([readonly]) { - border: 2px solid var(--input-color); - padding-top: 0; - margin-left: -1px; -} -.input-field.outlined input:focus:not([readonly]) + label, .input-field.outlined textarea:focus:not([readonly]) + label { - color: var(--input-color); -} -.input-field.outlined input:not(:-moz-placeholder) + label, .input-field.outlined textarea:not(:-moz-placeholder) + label { - top: -8px; - left: 16px; - margin-left: -4px; - padding: 0 4px; - background-color: transparent; -} -.input-field.outlined input:not(:-ms-input-placeholder) + label, .input-field.outlined textarea:not(:-ms-input-placeholder) + label { - top: -8px; - left: 16px; - margin-left: -4px; - padding: 0 4px; - background-color: transparent; -} -.input-field.outlined input:focus:not([readonly]) + label, .input-field.outlined input:not([placeholder=" "]) + label, .input-field.outlined input:not(:placeholder-shown) + label, .input-field.outlined textarea:focus:not([readonly]) + label, .input-field.outlined textarea:not([placeholder=" "]) + label, .input-field.outlined textarea:not(:placeholder-shown) + label { - top: -8px; - left: 16px; - margin-left: -4px; - padding: 0 4px; - background-color: transparent; -} -.input-field.outlined input:disabled, .input-field.outlined input[readonly=readonly], .input-field.outlined textarea:disabled, .input-field.outlined textarea[readonly=readonly] { - color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%); - border-color: color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%); -} -.input-field.error input, .input-field.error textarea { - border-color: var(--md-sys-color-error); -} -.input-field.error input:focus:not([readonly]), .input-field.error textarea:focus:not([readonly]) { - border-color: var(--md-sys-color-error); -} -.input-field.error input:focus:not([readonly]) + label, .input-field.error textarea:focus:not([readonly]) + label { - color: var(--md-sys-color-error); -} -.input-field.error label { - color: var(--md-sys-color-error); -} -.input-field.error .supporting-text { - color: var(--md-sys-color-error); -} -.input-field.error .suffix { - color: var(--md-sys-color-error); -} - -/* Inline */ -.inline { - display: inline-block; -} - -/* Search Field */ -.searchbar .prefix { - position: absolute; - padding-left: 1rem; - top: 0; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; -} -.searchbar > input { - border-width: 0; - background-color: transparent; - padding-left: 3rem; -} - -.searchbar.has-sidebar { - margin-left: 0; -} -@media only screen and (min-width : 993px) { - .searchbar.has-sidebar { - margin-left: 300px; - } -} - -/* -.input-field input[type=search] { - display: block; - line-height: inherit; - - .nav-wrapper & { - height: inherit; - padding-left: 4rem; - width: calc(100% - 4rem); - border: 0; - box-shadow: none; - } - &:focus:not(.browser-default) { - border: 0; - box-shadow: none; - } - & + .label-icon { - transform: none; - left: 1rem; - } -} -*/ -/* Textarea */ -textarea { - width: 100%; - height: 3rem; - background-color: transparent; -} -textarea.materialize-textarea { - padding-top: 26px !important; - padding-bottom: 4px !important; - line-height: normal; - overflow-y: hidden; /* prevents scroll bar flash */ - resize: none; - min-height: 3rem; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -.hiddendiv { - visibility: hidden; - white-space: pre-wrap; - word-wrap: break-word; - overflow-wrap: break-word; /* future version of deprecated 'word-wrap' */ - padding-top: 1.2rem; /* prevents text jump on Enter keypress */ - position: absolute; - top: 0; - z-index: -1; -} - -/* Autocomplete Items */ -.autocomplete-content li .highlight { - color: var(--md-sys-color-on-background); -} -.autocomplete-content li img { - height: 40px; - width: 40px; - margin: 5px 15px; -} - -/* Datepicker date input fields */ -.datepicker-date-input { - position: relative; - text-indent: -9999px; -} -.datepicker-date-input::after { - display: block; - position: absolute; - top: 1.1rem; - content: attr(data-date); - color: var(--input-color); - text-indent: 0; -} -.datepicker-date-input:focus-visible { - text-indent: 0; -} -.datepicker-date-input:focus-visible:after { - text-indent: -9999px; -} - -select.browser-default { - opacity: 1; - color: var(--md-sys-color-on-background); -} - -select { - background-color: var(--md-sys-color-surface); - width: 100%; - padding: 5px; - border: 1px solid var(--md-sys-color-outline-variant); - border-radius: 2px; - height: 3rem; -} - -.select-wrapper:focus-within { - outline: 2px solid var(--md-sys-color-primary); - border-radius: 4px; -} - -.select-wrapper { - position: relative; -} -.select-wrapper .caret { - position: absolute; - right: 0; - top: 0; - bottom: 0; - margin: auto 0; - z-index: 0; - fill: var(--md-sys-color-on-background); - pointer-events: none; -} -.select-wrapper .hide-select { - width: 0; - height: 0; - overflow: hidden; - position: absolute; - top: 0; - z-index: -1; -} - -select:disabled { - color: var(--md-sys-color-on-surface); -} - -.select-wrapper.disabled + label { - color: var(--md-sys-color-on-surface); -} -.select-wrapper.disabled .caret { - fill: var(--md-sys-color-on-surface); -} - -.select-wrapper input.select-dropdown:disabled { - color: var(--md-sys-color-on-surface); - cursor: default; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.select-wrapper i { - color: var(--md-sys-color-on-surface); -} - -.select-dropdown li.disabled, -.select-dropdown li.disabled > span, -.select-dropdown li.optgroup { - color: var(--md-sys-color-on-surface); -} - -.select-dropdown li img { - height: 40px; - width: 40px; - margin: 5px 15px; - -o-object-fit: cover; - object-fit: cover; - float: right; -} - -.select-dropdown li.optgroup { - border-top: 1px solid rgba(0, 0, 0, 0.04); -} -.select-dropdown li.optgroup.selected > span { - color: var(--md-sys-color-on-background); -} -.select-dropdown li.optgroup > span { - color: var(--md-sys-color-on-surface-variant); -} -.select-dropdown li.optgroup ~ li.optgroup-option { - padding-left: 1rem; -} - -.file-field { - display: grid; - grid-template-columns: -webkit-min-content auto; - grid-template-columns: min-content auto; - gap: 10px; -} -.file-field .file-path-wrapper { - overflow: hidden; -} -.file-field input.file-path { - width: 100%; -} -.file-field .btn { - height: 3rem; - line-height: 3rem; -} -.file-field span { - cursor: pointer; -} -.file-field input[type=file] { - position: absolute; - top: 0; - right: 0; - left: 0; - bottom: 0; - cursor: pointer; - width: 100%; - margin: 0; - padding: 0; - opacity: 0; - font-size: 20px; - filter: alpha(opacity=0); -} -.file-field input[type=file]::-webkit-file-upload-button { - display: none; -} - -/** -new approach for floating labels aka "form-fields" (css only) -- also use for selects, autocomplete, etc. - -
- -
- Given Name - - -
- -
- Family Name - - -
- -
- Birthmonth - - -
-
-*/ -:root { - --mw-font-size: 16px; - --mw-border-radius: 8px; - --mw-input-height: 56px; - --mw-idle-color: var(--md-sys-color-outline); - --mw-border-width: 1px; - --mw-hover-color: var(--md-sys-color-on-primary-container); - --mw-hover-border-width: 1px; - --mw-focus-color: var(--md-sys-color-primary); - --mw-focus-border-width: 2px; - --mw-disabled-color: #8886; - --mw-padding-left: 16px; - --mw-input-padding-x: var(--mw-padding-left); - --mw-input-padding-r: 12px; - --mw-label-padding: 4px; - --mw-inputlabel-duration: 0.2s; - --mw-inset: 5px; - /* calclated properties */ - --label-size: calc(var(--mw-font-size) * 0.75); - --label-margin-left: calc(var(--mw-padding-left) - var(--mw-label-padding)); - --half-inp: calc((-0.5 * var(--mw-input-height))); - --half-lbl: calc((0.5 * var(--label-size))); - --distY: calc(var(--half-inp) + var(--half-lbl)); -} - -/*=== idle */ -fieldset.form-field { - position: relative; - border-width: var(--mw-border-width); - border-color: var(--mw-idle-color); - border-style: solid; - border-radius: var(--mw-border-radius); - cursor: text; - height: var(--mw-input-height); - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - padding: 0; - margin: 0; - display: grid; - grid-auto-flow: column; - -webkit-box-align: baseline; - -webkit-align-items: baseline; - -ms-flex-align: baseline; - align-items: baseline; - font-size: var(--mw-font-size); - padding: 0 calc(var(--mw-inset) - var(--mw-border-width)); -} - -fieldset.form-field legend { - color: var(--mw-idle-color); - font-size: var(--label-size); - padding: 0 var(--mw-label-padding); - margin: 0; - margin-left: calc(var(--mw-padding-left) - var(--mw-label-padding) - var(--mw-border-width)); - cursor: text; - /* color: transparent; */ - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -fieldset.form-field input, -fieldset.form-field select { - --mw-calc-input-height: calc( - var(--mw-input-height) - var(--label-size) + 2 * var(--mw-border-width) - ); - -webkit-box-sizing: border-box; - box-sizing: border-box; - font-size: var(--mw-font-size); - padding: 0; - margin: 0; - width: 100%; - height: var(--mw-calc-input-height); - max-height: var(--mw-calc-input-height); - margin-top: calc(-1 * var(--half-lbl)); - padding-left: calc(var(--mw-padding-left) - var(--mw-border-width)); - border: none; - line-height: normal; - outline: none; - background: none; - /* background-color: #0f05 !important; */ -} - -fieldset.form-field select { - padding: 0; - /* margin: 0; */ - padding-left: calc(var(--mw-padding-left) - var(--mw-label-padding)); - /* background-color: #f005 !important; */ - z-index: 2; -} - -fieldset.form-field select option { - background-color: black; - color: white; -} - -fieldset.form-field input::-webkit-input-placeholder { - color: var(--mw-idle-color); - font-size: var(--mw-font-size); -} - -fieldset.form-field input::-moz-placeholder { - color: var(--mw-idle-color); - font-size: var(--mw-font-size); -} - -fieldset.form-field input:-ms-input-placeholder { - color: var(--mw-idle-color); - font-size: var(--mw-font-size); -} - -fieldset.form-field input::-ms-input-placeholder { - color: var(--mw-idle-color); - font-size: var(--mw-font-size); -} - -fieldset.form-field input::placeholder { - color: var(--mw-idle-color); - font-size: var(--mw-font-size); -} - -fieldset.form-field label { - position: absolute; - top: calc(var(--mw-input-height) / 2 - var(--label-size) - var(--mw-font-size) / 2); - margin-left: calc(var(--mw-inset) - var(--mw-border-width)); - font-size: var(--mw-font-size); - cursor: text; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - color: transparent; - /* color: green; */ - z-index: 1; /* for not blocking klicks */ - pointer-events: none; -} - -/* fixes from other inputs */ -fieldset.form-field .select-wrapper { - outline: none !important; -} - -/*--- idle animated */ -fieldset.form-field.animated legend::before { - content: ""; - position: absolute; - display: block; - width: calc(100% - var(--mw-border-radius)); - right: calc(0.5 * var(--mw-border-radius)); - height: 0; - border-top: var(--mw-border-width) solid var(--mw-idle-color); - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; - -webkit-transition: width calc(var(--mw-inputlabel-duration) * 0.8); - transition: width calc(var(--mw-inputlabel-duration) * 0.8); -} - -fieldset.form-field.animated legend { - color: transparent; -} - -fieldset.form-field.animated input::-webkit-input-placeholder { - opacity: 1; - -webkit-transition: opacity var(--mw-inputlabel-duration) step-end; - transition: opacity var(--mw-inputlabel-duration) step-end; -} - -fieldset.form-field.animated input::-moz-placeholder { - opacity: 1; - -moz-transition: opacity var(--mw-inputlabel-duration) step-end; - transition: opacity var(--mw-inputlabel-duration) step-end; -} - -fieldset.form-field.animated input:-ms-input-placeholder { - opacity: 1; - -ms-transition: opacity var(--mw-inputlabel-duration) step-end; - transition: opacity var(--mw-inputlabel-duration) step-end; -} - -fieldset.form-field.animated input::-ms-input-placeholder { - opacity: 1; - -ms-transition: opacity var(--mw-inputlabel-duration) step-end; - transition: opacity var(--mw-inputlabel-duration) step-end; -} - -fieldset.form-field.animated input::placeholder { - opacity: 1; - -webkit-transition: opacity var(--mw-inputlabel-duration) step-end; - transition: opacity var(--mw-inputlabel-duration) step-end; -} - -fieldset.form-field.animated label { - position: absolute; - left: calc(var(--mw-input-padding-x) - var(--mw-border-width)); - font-size: var(--mw-font-size); - -webkit-transition: font-size var(--mw-inputlabel-duration), opacity var(--mw-inputlabel-duration) step-end, -webkit-transform var(--mw-inputlabel-duration); - transition: font-size var(--mw-inputlabel-duration), opacity var(--mw-inputlabel-duration) step-end, -webkit-transform var(--mw-inputlabel-duration); - transition: font-size var(--mw-inputlabel-duration), transform var(--mw-inputlabel-duration), opacity var(--mw-inputlabel-duration) step-end; - transition: font-size var(--mw-inputlabel-duration), transform var(--mw-inputlabel-duration), opacity var(--mw-inputlabel-duration) step-end, -webkit-transform var(--mw-inputlabel-duration); -} - -/*--- idle animated populated */ -fieldset.form-field.animated:has(input:not(:-moz-placeholder)) legend::before { - width: 0; -} -fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)) legend::before { - width: 0; -} -fieldset.form-field.animated:has(input:not(:placeholder-shown)) legend::before { - width: 0; -} - -fieldset.form-field.animated:has(input:not(:-moz-placeholder)) legend { - color: var(--mw-idle-color); -} - -fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)) legend { - color: var(--mw-idle-color); -} - -fieldset.form-field.animated:has(input:not(:placeholder-shown)) legend { - color: var(--mw-idle-color); -} - -fieldset.form-field.animated:has(input:not(:-moz-placeholder)) label { - color: transparent; -} - -fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)) label { - color: transparent; -} - -fieldset.form-field.animated:has(input:not(:placeholder-shown)) label { - color: transparent; -} - -/*===== hovered */ -fieldset.form-field:hover { - border-width: var(--mw-hover-border-width); - border-color: var(--mw-hover-color); - padding: 0 calc(var(--mw-inset) - var(--mw-hover-border-width)); -} - -fieldset.form-field:hover legend::before { - border-width: var(--mw-hover-border-width); - border-color: var(--mw-hover-color); -} - -fieldset.form-field:hover legend { - color: var(--mw-hover-color); -} - -/* hovered animated */ -fieldset.form-field.animated:hover legend { - color: transparent; -} - -fieldset.form-field.animated:has(input:placeholder-shown):hover input::-webkit-input-placeholder { - color: transparent; -} - -fieldset.form-field.animated:has(input:placeholder-shown):hover input::-moz-placeholder { - color: transparent; -} - -fieldset.form-field.animated:has(input:placeholder-shown):hover input:-ms-input-placeholder { - color: transparent; -} - -fieldset.form-field.animated:has(input:placeholder-shown):hover input::-ms-input-placeholder { - color: transparent; -} - -fieldset.form-field.animated:has(input:-moz-placeholder):hover input::placeholder { - color: transparent; -} - -fieldset.form-field.animated:has(input:-ms-input-placeholder):hover input::placeholder { - color: transparent; -} - -fieldset.form-field.animated:has(input:placeholder-shown):hover input::placeholder { - color: transparent; -} - -fieldset.form-field.animated:has(input:not(:-moz-placeholder)):hover legend { - color: var(--mw-hover-color); -} - -fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)):hover legend { - color: var(--mw-hover-color); -} - -fieldset.form-field.animated:has(input:not(:placeholder-shown)):hover legend { - color: var(--mw-hover-color); -} - -fieldset.form-field.animated:hover label { - /* color: transparent; */ - color: var(--mw-hover-color); - left: calc(var(--mw-input-padding-x) - var(--mw-hover-border-width)); - top: calc(0.5 * var(--mw-input-height) - var(--label-size) * 0.5 - var(--mw-font-size) + var(--mw-hover-border-width)); -} - -/*===== focused */ -fieldset.form-field:focus-within { - border-width: var(--mw-focus-border-width); - border-color: var(--mw-focus-color); - padding: 0 calc(var(--mw-inset) - var(--mw-focus-border-width)); -} - -fieldset.form-field:focus-within legend::before { - border-width: var(--mw-focus-border-width); - border-color: var(--mw-focus-color); -} - -fieldset.form-field:focus-within legend { - color: var(--mw-focus-color); -} - -fieldset.form-field select:focus { - color: var(--mw-focus-color); -} - -/* focused animated */ -fieldset.form-field.animated:focus-within legend::before { - width: 0; -} - -fieldset.form-field.animated:focus-within legend { - color: var(--mw-focus-color); -} - -fieldset.form-field.animated:has(input:not(:-moz-placeholder)):focus-within legend { - color: var(--mw-focus-color); -} - -fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)):focus-within legend { - color: var(--mw-focus-color); -} - -fieldset.form-field.animated:has(input:not(:placeholder-shown)):focus-within legend { - color: var(--mw-focus-color); -} - -fieldset.form-field.animated:focus-within input::-webkit-input-placeholder { - color: transparent; -} - -fieldset.form-field.animated:focus-within input::-moz-placeholder { - color: transparent; -} - -fieldset.form-field.animated:focus-within input:-ms-input-placeholder { - color: transparent; -} - -fieldset.form-field.animated:focus-within input::-ms-input-placeholder { - color: transparent; -} - -fieldset.form-field.animated:focus-within input::placeholder { - color: transparent; -} - -fieldset.form-field.animated:focus-within label { - color: transparent; - left: calc(var(--mw-input-padding-x) - var(--mw-hover-border-width)); -} - -/* -fieldset.form-field.animated input:not(:placeholder-shown) ~ legend::before { - width: 0; -} -fieldset.form-field.animated input:not(:placeholder-shown) ~ label { - font-size: var(--label-size); - transform: translateY(0); - opacity: 1; -} -fieldset.form-field.animated label { - opacity: 1; - color: var(--mw-focus-color); - font-size: var(--label-size); - transform: translateY(var(--distY)) translateX(var(--mw-input-padding-x)); - transition: font-size var(--mw-inputlabel-duration), transform var(--mw-inputlabel-duration), opacity 0s; -} -fieldset.form-field.animated:focus-within legend::before, -fieldset.form-field.animated:has(input:not(:placeholder-shown)) legend::before { - border-top: var(--mw-focus-border-width) solid var(--mw-focus-color); - width: 0; -} -fieldset.form-field.animated:focus-within input::placeholder { - opacity: 0; - transition: opacity 0s; -} -*/ -/* disabled*/ -fieldset.form-field[disabled], -fieldset.form-field[disabled]:hover { - background-color: transparent; - border-color: var(--mw-disabled-color); - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: not-allowed; - padding: 0 calc(var(--mw-inset) - var(--mw-border-width)); -} - -fieldset.form-field[disabled] input { - cursor: not-allowed; -} - -fieldset.form-field[disabled] input::-webkit-input-placeholder { - color: var(--mw-disabled-color); - cursor: not-allowed; -} - -fieldset.form-field[disabled] input::-moz-placeholder { - color: var(--mw-disabled-color); - cursor: not-allowed; -} - -fieldset.form-field[disabled] input:-ms-input-placeholder { - color: var(--mw-disabled-color); - cursor: not-allowed; -} - -fieldset.form-field[disabled] input::-ms-input-placeholder { - color: var(--mw-disabled-color); - cursor: not-allowed; -} - -fieldset.form-field[disabled] legend, -fieldset.form-field[disabled] input::placeholder { - color: var(--mw-disabled-color); - cursor: not-allowed; -} - -fieldset.form-field[disabled] input { - height: calc(var(--mw-input-height) - var(--label-size) + 2 * var(--mw-border-width)); - margin-top: calc(-1 * var(--half-lbl)); -} - -fieldset.form-field[disabled]:hover { - border-width: var(--mw-border-width); -} - -fieldset.form-field[disabled]:hover input, -fieldset.form-field[disabled]:hover select { - padding-left: calc(var(--mw-padding-left) - var(--mw-border-width)); -} - -fieldset.form-field[disabled]:hover legend { - margin-left: calc(var(--mw-padding-left) - var(--mw-label-padding) - var(--mw-border-width)); - border-color: transparent; - border-color: var(--mw-disabled-color); - color: var(--mw-disabled-color); - cursor: not-allowed; -} - -fieldset.form-field[disabled] label { - cursor: not-allowed; -} - -/* special: required */ -fieldset.form-field:has([required]) legend::after { - content: " *"; -} - -fieldset.form-field:has([required]) label::after { - content: " *"; -} \ No newline at end of file diff --git a/dist/css/materialize.min.css b/dist/css/materialize.min.css deleted file mode 100644 index 5dbb37df7a..0000000000 --- a/dist/css/materialize.min.css +++ /dev/null @@ -1,6 +0,0 @@ -/*! -* Materialize v2.3.3 (https://materializeweb.com) -* Copyright 2014-2026 Materialize -* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE) -*/ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}:root{--md-source: #006495;--md-ref-palette-primary0: #000000;--md-ref-palette-primary10: #001e30;--md-ref-palette-primary20: #003450;--md-ref-palette-primary25: #003f60;--md-ref-palette-primary30: #004b71;--md-ref-palette-primary35: #005783;--md-ref-palette-primary40: #006495;--md-ref-palette-primary50: #0f7eb8;--md-ref-palette-primary60: #3d98d4;--md-ref-palette-primary70: #5db3f0;--md-ref-palette-primary80: #8fcdff;--md-ref-palette-primary90: #cbe6ff;--md-ref-palette-primary95: #e6f2ff;--md-ref-palette-primary98: #f7f9ff;--md-ref-palette-primary99: #fcfcff;--md-ref-palette-primary100: #ffffff;--md-ref-palette-secondary0: #000000;--md-ref-palette-secondary10: #0d1d29;--md-ref-palette-secondary20: #22323f;--md-ref-palette-secondary25: #2d3d4b;--md-ref-palette-secondary30: #394856;--md-ref-palette-secondary35: #445462;--md-ref-palette-secondary40: #50606f;--md-ref-palette-secondary50: #697988;--md-ref-palette-secondary60: #8293a2;--md-ref-palette-secondary70: #9dadbd;--md-ref-palette-secondary80: #b8c8d9;--md-ref-palette-secondary90: #d4e4f6;--md-ref-palette-secondary95: #e6f2ff;--md-ref-palette-secondary98: #f7f9ff;--md-ref-palette-secondary99: #fcfcff;--md-ref-palette-secondary100: #ffffff;--md-ref-palette-tertiary0: #000000;--md-ref-palette-tertiary10: #211634;--md-ref-palette-tertiary20: #362b4a;--md-ref-palette-tertiary25: #423656;--md-ref-palette-tertiary30: #4d4162;--md-ref-palette-tertiary35: #594c6e;--md-ref-palette-tertiary40: #66587b;--md-ref-palette-tertiary50: #7f7195;--md-ref-palette-tertiary60: #998ab0;--md-ref-palette-tertiary70: #b4a4cb;--md-ref-palette-tertiary80: #d0bfe7;--md-ref-palette-tertiary90: #ecdcff;--md-ref-palette-tertiary95: #f7edff;--md-ref-palette-tertiary98: #fef7ff;--md-ref-palette-tertiary99: #fffbff;--md-ref-palette-tertiary100: #ffffff;--md-ref-palette-neutral0: #000000;--md-ref-palette-neutral10: #1a1c1e;--md-ref-palette-neutral20: #2e3133;--md-ref-palette-neutral25: #3a3c3e;--md-ref-palette-neutral30: #454749;--md-ref-palette-neutral35: #515255;--md-ref-palette-neutral40: #5d5e61;--md-ref-palette-neutral50: #76777a;--md-ref-palette-neutral60: #8f9194;--md-ref-palette-neutral70: #aaabae;--md-ref-palette-neutral80: #c6c6c9;--md-ref-palette-neutral90: #e2e2e5;--md-ref-palette-neutral95: #f0f0f3;--md-ref-palette-neutral98: #f9f9fc;--md-ref-palette-neutral99: #fcfcff;--md-ref-palette-neutral100: #ffffff;--md-ref-palette-neutral-variant0: #000000;--md-ref-palette-neutral-variant10: #161c22;--md-ref-palette-neutral-variant20: #2b3137;--md-ref-palette-neutral-variant25: #363c42;--md-ref-palette-neutral-variant30: #41474d;--md-ref-palette-neutral-variant35: #4d5359;--md-ref-palette-neutral-variant40: #595f65;--md-ref-palette-neutral-variant50: #72787e;--md-ref-palette-neutral-variant60: #8b9198;--md-ref-palette-neutral-variant70: #a6acb3;--md-ref-palette-neutral-variant80: #c1c7ce;--md-ref-palette-neutral-variant90: #dee3ea;--md-ref-palette-neutral-variant95: #ecf1f9;--md-ref-palette-neutral-variant98: #f7f9ff;--md-ref-palette-neutral-variant99: #fcfcff;--md-ref-palette-neutral-variant100: #ffffff;--md-ref-palette-error0: #000000;--md-ref-palette-error10: #410002;--md-ref-palette-error20: #690005;--md-ref-palette-error25: #7e0007;--md-ref-palette-error30: #93000a;--md-ref-palette-error35: #a80710;--md-ref-palette-error40: #ba1a1a;--md-ref-palette-error50: #de3730;--md-ref-palette-error60: #ff5449;--md-ref-palette-error70: #ff897d;--md-ref-palette-error80: #ffb4ab;--md-ref-palette-error90: #ffdad6;--md-ref-palette-error95: #ffedea;--md-ref-palette-error98: #fff8f7;--md-ref-palette-error99: #fffbff;--md-ref-palette-error100: #ffffff;--md-sys-color-primary-light: #006495;--md-sys-color-on-primary-light: #ffffff;--md-sys-color-primary-container-light: #cbe6ff;--md-sys-color-on-primary-container-light: #001e30;--md-sys-color-secondary-light: #50606f;--md-sys-color-on-secondary-light: #ffffff;--md-sys-color-secondary-container-light: #d4e4f6;--md-sys-color-on-secondary-container-light: #0d1d29;--md-sys-color-tertiary-light: #66587b;--md-sys-color-on-tertiary-light: #ffffff;--md-sys-color-tertiary-container-light: #ecdcff;--md-sys-color-on-tertiary-container-light: #211634;--md-sys-color-error-light: #ba1a1a;--md-sys-color-error-container-light: #ffdad6;--md-sys-color-on-error-light: #ffffff;--md-sys-color-on-error-container-light: #410002;--md-sys-color-background-light: #fcfcff;--md-sys-color-on-background-light: #1a1c1e;--md-sys-color-surface-light: #fcfcff;--md-sys-color-on-surface-light: #1a1c1e;--md-sys-color-surface-variant-light: #dee3ea;--md-sys-color-on-surface-variant-light: #41474d;--md-sys-color-outline-light: #72787e;--md-sys-color-inverse-on-surface-light: #f0f0f3;--md-sys-color-inverse-surface-light: #2e3133;--md-sys-color-inverse-primary-light: #8fcdff;--md-sys-color-shadow-light: #000000;--md-sys-color-surface-tint-light: #006495;--md-sys-color-outline-variant-light: #c1c7ce;--md-sys-color-scrim-light: #000000;--md-sys-color-primary-dark: #8fcdff;--md-sys-color-on-primary-dark: #003450;--md-sys-color-primary-container-dark: #004b71;--md-sys-color-on-primary-container-dark: #cbe6ff;--md-sys-color-secondary-dark: #b8c8d9;--md-sys-color-on-secondary-dark: #22323f;--md-sys-color-secondary-container-dark: #394856;--md-sys-color-on-secondary-container-dark: #d4e4f6;--md-sys-color-tertiary-dark: #d0bfe7;--md-sys-color-on-tertiary-dark: #362b4a;--md-sys-color-tertiary-container-dark: #4d4162;--md-sys-color-on-tertiary-container-dark: #ecdcff;--md-sys-color-error-dark: #ffb4ab;--md-sys-color-error-container-dark: #93000a;--md-sys-color-on-error-dark: #690005;--md-sys-color-on-error-container-dark: #ffdad6;--md-sys-color-background-dark: #1a1c1e;--md-sys-color-on-background-dark: #e2e2e5;--md-sys-color-surface-dark: #1a1c1e;--md-sys-color-on-surface-dark: #e2e2e5;--md-sys-color-surface-variant-dark: #41474d;--md-sys-color-on-surface-variant-dark: #c1c7ce;--md-sys-color-outline-dark: #8b9198;--md-sys-color-inverse-on-surface-dark: #1a1c1e;--md-sys-color-inverse-surface-dark: #e2e2e5;--md-sys-color-inverse-primary-dark: #006495;--md-sys-color-shadow-dark: #000000;--md-sys-color-surface-tint-dark: #8fcdff;--md-sys-color-outline-variant-dark: #41474d;--md-sys-color-scrim-dark: #000000;--md-sys-typescale-display-large-font-family-name: Roboto;--md-sys-typescale-display-large-font-family-style: Regular;--md-sys-typescale-display-large-font-weight: 400px;--md-sys-typescale-display-large-font-size: 57px;--md-sys-typescale-display-large-line-height: 64px;--md-sys-typescale-display-large-letter-spacing: -0.25px;--md-sys-typescale-display-medium-font-family-name: Roboto;--md-sys-typescale-display-medium-font-family-style: Regular;--md-sys-typescale-display-medium-font-weight: 400px;--md-sys-typescale-display-medium-font-size: 45px;--md-sys-typescale-display-medium-line-height: 52px;--md-sys-typescale-display-medium-letter-spacing: 0px;--md-sys-typescale-display-small-font-family-name: Roboto;--md-sys-typescale-display-small-font-family-style: Regular;--md-sys-typescale-display-small-font-weight: 400px;--md-sys-typescale-display-small-font-size: 36px;--md-sys-typescale-display-small-line-height: 44px;--md-sys-typescale-display-small-letter-spacing: 0px;--md-sys-typescale-headline-large-font-family-name: Roboto;--md-sys-typescale-headline-large-font-family-style: Regular;--md-sys-typescale-headline-large-font-weight: 400px;--md-sys-typescale-headline-large-font-size: 32px;--md-sys-typescale-headline-large-line-height: 40px;--md-sys-typescale-headline-large-letter-spacing: 0px;--md-sys-typescale-headline-medium-font-family-name: Roboto;--md-sys-typescale-headline-medium-font-family-style: Regular;--md-sys-typescale-headline-medium-font-weight: 400px;--md-sys-typescale-headline-medium-font-size: 28px;--md-sys-typescale-headline-medium-line-height: 36px;--md-sys-typescale-headline-medium-letter-spacing: 0px;--md-sys-typescale-headline-small-font-family-name: Roboto;--md-sys-typescale-headline-small-font-family-style: Regular;--md-sys-typescale-headline-small-font-weight: 400px;--md-sys-typescale-headline-small-font-size: 24px;--md-sys-typescale-headline-small-line-height: 32px;--md-sys-typescale-headline-small-letter-spacing: 0px;--md-sys-typescale-body-large-font-family-name: Roboto;--md-sys-typescale-body-large-font-family-style: Regular;--md-sys-typescale-body-large-font-weight: 400px;--md-sys-typescale-body-large-font-size: 16px;--md-sys-typescale-body-large-line-height: 24px;--md-sys-typescale-body-large-letter-spacing: 0.50px;--md-sys-typescale-body-medium-font-family-name: Roboto;--md-sys-typescale-body-medium-font-family-style: Regular;--md-sys-typescale-body-medium-font-weight: 400px;--md-sys-typescale-body-medium-font-size: 14px;--md-sys-typescale-body-medium-line-height: 20px;--md-sys-typescale-body-medium-letter-spacing: 0.25px;--md-sys-typescale-body-small-font-family-name: Roboto;--md-sys-typescale-body-small-font-family-style: Regular;--md-sys-typescale-body-small-font-weight: 400px;--md-sys-typescale-body-small-font-size: 12px;--md-sys-typescale-body-small-line-height: 16px;--md-sys-typescale-body-small-letter-spacing: 0.40px;--md-sys-typescale-label-large-font-family-name: Roboto;--md-sys-typescale-label-large-font-family-style: Medium;--md-sys-typescale-label-large-font-weight: 500px;--md-sys-typescale-label-large-font-size: 14px;--md-sys-typescale-label-large-line-height: 20px;--md-sys-typescale-label-large-letter-spacing: 0.10px;--md-sys-typescale-label-medium-font-family-name: Roboto;--md-sys-typescale-label-medium-font-family-style: Medium;--md-sys-typescale-label-medium-font-weight: 500px;--md-sys-typescale-label-medium-font-size: 12px;--md-sys-typescale-label-medium-line-height: 16px;--md-sys-typescale-label-medium-letter-spacing: 0.50px;--md-sys-typescale-label-small-font-family-name: Roboto;--md-sys-typescale-label-small-font-family-style: Medium;--md-sys-typescale-label-small-font-weight: 500px;--md-sys-typescale-label-small-font-size: 11px;--md-sys-typescale-label-small-line-height: 16px;--md-sys-typescale-label-small-letter-spacing: 0.50px;--md-sys-typescale-title-large-font-family-name: Roboto;--md-sys-typescale-title-large-font-family-style: Regular;--md-sys-typescale-title-large-font-weight: 400px;--md-sys-typescale-title-large-font-size: 22px;--md-sys-typescale-title-large-line-height: 28px;--md-sys-typescale-title-large-letter-spacing: 0px;--md-sys-typescale-title-medium-font-family-name: Roboto;--md-sys-typescale-title-medium-font-family-style: Medium;--md-sys-typescale-title-medium-font-weight: 500px;--md-sys-typescale-title-medium-font-size: 16px;--md-sys-typescale-title-medium-line-height: 24px;--md-sys-typescale-title-medium-letter-spacing: 0.15px;--md-sys-typescale-title-small-font-family-name: Roboto;--md-sys-typescale-title-small-font-family-style: Medium;--md-sys-typescale-title-small-font-weight: 500px;--md-sys-typescale-title-small-font-size: 14px;--md-sys-typescale-title-small-line-height: 20px;--md-sys-typescale-title-small-letter-spacing: 0.10px}:root,:host{color-scheme:light;--md-sys-color-primary: var(--md-sys-color-primary-light);--md-sys-color-on-primary: var(--md-sys-color-on-primary-light);--md-sys-color-primary-container: var(--md-sys-color-primary-container-light);--md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-light);--md-sys-color-secondary: var(--md-sys-color-secondary-light);--md-sys-color-on-secondary: var(--md-sys-color-on-secondary-light);--md-sys-color-secondary-container: var(--md-sys-color-secondary-container-light);--md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-light);--md-sys-color-tertiary: var(--md-sys-color-tertiary-light);--md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-light);--md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-light);--md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-light);--md-sys-color-error: var(--md-sys-color-error-light);--md-sys-color-on-error: var(--md-sys-color-on-error-light);--md-sys-color-error-container: var(--md-sys-color-error-container-light);--md-sys-color-on-error-container: var(--md-sys-color-on-error-container-light);--md-sys-color-outline: var(--md-sys-color-outline-light);--md-sys-color-background: var(--md-sys-color-background-light);--md-sys-color-on-background: var(--md-sys-color-on-background-light);--md-sys-color-surface: var(--md-sys-color-surface-light);--md-sys-color-on-surface: var(--md-sys-color-on-surface-light);--md-sys-color-surface-variant: var(--md-sys-color-surface-variant-light);--md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-light);--md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-light);--md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-light);--md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-light);--md-sys-color-shadow: var(--md-sys-color-shadow-light);--md-sys-color-surface-tint: var(--md-sys-color-surface-tint-light);--md-sys-color-outline-variant: var(--md-sys-color-outline-variant-light);--md-sys-color-scrim: var(--md-sys-color-scrim-light)}@media(prefers-color-scheme: dark){:root,:host{color-scheme:dark;--md-sys-color-primary: var(--md-sys-color-primary-dark);--md-sys-color-on-primary: var(--md-sys-color-on-primary-dark);--md-sys-color-primary-container: var(--md-sys-color-primary-container-dark);--md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-dark);--md-sys-color-secondary: var(--md-sys-color-secondary-dark);--md-sys-color-on-secondary: var(--md-sys-color-on-secondary-dark);--md-sys-color-secondary-container: var(--md-sys-color-secondary-container-dark);--md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-dark);--md-sys-color-tertiary: var(--md-sys-color-tertiary-dark);--md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-dark);--md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-dark);--md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-dark);--md-sys-color-error: var(--md-sys-color-error-dark);--md-sys-color-on-error: var(--md-sys-color-on-error-dark);--md-sys-color-error-container: var(--md-sys-color-error-container-dark);--md-sys-color-on-error-container: var(--md-sys-color-on-error-container-dark);--md-sys-color-outline: var(--md-sys-color-outline-dark);--md-sys-color-background: var(--md-sys-color-background-dark);--md-sys-color-on-background: var(--md-sys-color-on-background-dark);--md-sys-color-surface: var(--md-sys-color-surface-dark);--md-sys-color-on-surface: var(--md-sys-color-on-surface-dark);--md-sys-color-surface-variant: var(--md-sys-color-surface-variant-dark);--md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-dark);--md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-dark);--md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-dark);--md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-dark);--md-sys-color-shadow: var(--md-sys-color-shadow-dark);--md-sys-color-surface-tint: var(--md-sys-color-surface-tint-dark);--md-sys-color-outline-variant: var(--md-sys-color-outline-variant-dark);--md-sys-color-scrim: var(--md-sys-color-scrim-dark)}}:root[theme=light]{color-scheme:light;--md-sys-color-primary: var(--md-sys-color-primary-light);--md-sys-color-on-primary: var(--md-sys-color-on-primary-light);--md-sys-color-primary-container: var(--md-sys-color-primary-container-light);--md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-light);--md-sys-color-secondary: var(--md-sys-color-secondary-light);--md-sys-color-on-secondary: var(--md-sys-color-on-secondary-light);--md-sys-color-secondary-container: var(--md-sys-color-secondary-container-light);--md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-light);--md-sys-color-tertiary: var(--md-sys-color-tertiary-light);--md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-light);--md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-light);--md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-light);--md-sys-color-error: var(--md-sys-color-error-light);--md-sys-color-on-error: var(--md-sys-color-on-error-light);--md-sys-color-error-container: var(--md-sys-color-error-container-light);--md-sys-color-on-error-container: var(--md-sys-color-on-error-container-light);--md-sys-color-outline: var(--md-sys-color-outline-light);--md-sys-color-background: var(--md-sys-color-background-light);--md-sys-color-on-background: var(--md-sys-color-on-background-light);--md-sys-color-surface: var(--md-sys-color-surface-light);--md-sys-color-on-surface: var(--md-sys-color-on-surface-light);--md-sys-color-surface-variant: var(--md-sys-color-surface-variant-light);--md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-light);--md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-light);--md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-light);--md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-light);--md-sys-color-shadow: var(--md-sys-color-shadow-light);--md-sys-color-surface-tint: var(--md-sys-color-surface-tint-light);--md-sys-color-outline-variant: var(--md-sys-color-outline-variant-light);--md-sys-color-scrim: var(--md-sys-color-scrim-light)}:root[theme=dark]{color-scheme:dark;--md-sys-color-primary: var(--md-sys-color-primary-dark);--md-sys-color-on-primary: var(--md-sys-color-on-primary-dark);--md-sys-color-primary-container: var(--md-sys-color-primary-container-dark);--md-sys-color-on-primary-container: var(--md-sys-color-on-primary-container-dark);--md-sys-color-secondary: var(--md-sys-color-secondary-dark);--md-sys-color-on-secondary: var(--md-sys-color-on-secondary-dark);--md-sys-color-secondary-container: var(--md-sys-color-secondary-container-dark);--md-sys-color-on-secondary-container: var(--md-sys-color-on-secondary-container-dark);--md-sys-color-tertiary: var(--md-sys-color-tertiary-dark);--md-sys-color-on-tertiary: var(--md-sys-color-on-tertiary-dark);--md-sys-color-tertiary-container: var(--md-sys-color-tertiary-container-dark);--md-sys-color-on-tertiary-container: var(--md-sys-color-on-tertiary-container-dark);--md-sys-color-error: var(--md-sys-color-error-dark);--md-sys-color-on-error: var(--md-sys-color-on-error-dark);--md-sys-color-error-container: var(--md-sys-color-error-container-dark);--md-sys-color-on-error-container: var(--md-sys-color-on-error-container-dark);--md-sys-color-outline: var(--md-sys-color-outline-dark);--md-sys-color-background: var(--md-sys-color-background-dark);--md-sys-color-on-background: var(--md-sys-color-on-background-dark);--md-sys-color-surface: var(--md-sys-color-surface-dark);--md-sys-color-on-surface: var(--md-sys-color-on-surface-dark);--md-sys-color-surface-variant: var(--md-sys-color-surface-variant-dark);--md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-variant-dark);--md-sys-color-inverse-surface: var(--md-sys-color-inverse-surface-dark);--md-sys-color-inverse-on-surface: var(--md-sys-color-inverse-on-surface-dark);--md-sys-color-inverse-primary: var(--md-sys-color-inverse-primary-dark);--md-sys-color-shadow: var(--md-sys-color-shadow-dark);--md-sys-color-surface-tint: var(--md-sys-color-surface-tint-dark);--md-sys-color-outline-variant: var(--md-sys-color-outline-variant-dark);--md-sys-color-scrim: var(--md-sys-color-scrim-dark)}.display-large{font-family:var(--md-sys-typescale-display-large-font-family-name);font-style:var(--md-sys-typescale-display-large-font-family-style);font-weight:var(--md-sys-typescale-display-large-font-weight);font-size:var(--md-sys-typescale-display-large-font-size);letter-spacing:var(--md-sys-typescale-display-large-tracking);line-height:var(--md-sys-typescale-display-large-height);text-transform:var(--md-sys-typescale-display-large-text-transform);-webkit-text-decoration:var(--md-sys-typescale-display-large-text-decoration);text-decoration:var(--md-sys-typescale-display-large-text-decoration)}.display-medium{font-family:var(--md-sys-typescale-display-medium-font-family-name);font-style:var(--md-sys-typescale-display-medium-font-family-style);font-weight:var(--md-sys-typescale-display-medium-font-weight);font-size:var(--md-sys-typescale-display-medium-font-size);letter-spacing:var(--md-sys-typescale-display-medium-tracking);line-height:var(--md-sys-typescale-display-medium-height);text-transform:var(--md-sys-typescale-display-medium-text-transform);-webkit-text-decoration:var(--md-sys-typescale-display-medium-text-decoration);text-decoration:var(--md-sys-typescale-display-medium-text-decoration)}.display-small{font-family:var(--md-sys-typescale-display-small-font-family-name);font-style:var(--md-sys-typescale-display-small-font-family-style);font-weight:var(--md-sys-typescale-display-small-font-weight);font-size:var(--md-sys-typescale-display-small-font-size);letter-spacing:var(--md-sys-typescale-display-small-tracking);line-height:var(--md-sys-typescale-display-small-height);text-transform:var(--md-sys-typescale-display-small-text-transform);-webkit-text-decoration:var(--md-sys-typescale-display-small-text-decoration);text-decoration:var(--md-sys-typescale-display-small-text-decoration)}.headline-large{font-family:var(--md-sys-typescale-headline-large-font-family-name);font-style:var(--md-sys-typescale-headline-large-font-family-style);font-weight:var(--md-sys-typescale-headline-large-font-weight);font-size:var(--md-sys-typescale-headline-large-font-size);letter-spacing:var(--md-sys-typescale-headline-large-tracking);line-height:var(--md-sys-typescale-headline-large-height);text-transform:var(--md-sys-typescale-headline-large-text-transform);-webkit-text-decoration:var(--md-sys-typescale-headline-large-text-decoration);text-decoration:var(--md-sys-typescale-headline-large-text-decoration)}.headline-medium{font-family:var(--md-sys-typescale-headline-medium-font-family-name);font-style:var(--md-sys-typescale-headline-medium-font-family-style);font-weight:var(--md-sys-typescale-headline-medium-font-weight);font-size:var(--md-sys-typescale-headline-medium-font-size);letter-spacing:var(--md-sys-typescale-headline-medium-tracking);line-height:var(--md-sys-typescale-headline-medium-height);text-transform:var(--md-sys-typescale-headline-medium-text-transform);-webkit-text-decoration:var(--md-sys-typescale-headline-medium-text-decoration);text-decoration:var(--md-sys-typescale-headline-medium-text-decoration)}.headline-small{font-family:var(--md-sys-typescale-headline-small-font-family-name);font-style:var(--md-sys-typescale-headline-small-font-family-style);font-weight:var(--md-sys-typescale-headline-small-font-weight);font-size:var(--md-sys-typescale-headline-small-font-size);letter-spacing:var(--md-sys-typescale-headline-small-tracking);line-height:var(--md-sys-typescale-headline-small-height);text-transform:var(--md-sys-typescale-headline-small-text-transform);-webkit-text-decoration:var(--md-sys-typescale-headline-small-text-decoration);text-decoration:var(--md-sys-typescale-headline-small-text-decoration)}.body-large{font-family:var(--md-sys-typescale-body-large-font-family-name);font-style:var(--md-sys-typescale-body-large-font-family-style);font-weight:var(--md-sys-typescale-body-large-font-weight);font-size:var(--md-sys-typescale-body-large-font-size);letter-spacing:var(--md-sys-typescale-body-large-tracking);line-height:var(--md-sys-typescale-body-large-height);text-transform:var(--md-sys-typescale-body-large-text-transform);-webkit-text-decoration:var(--md-sys-typescale-body-large-text-decoration);text-decoration:var(--md-sys-typescale-body-large-text-decoration)}.body-medium{font-family:var(--md-sys-typescale-body-medium-font-family-name);font-style:var(--md-sys-typescale-body-medium-font-family-style);font-weight:var(--md-sys-typescale-body-medium-font-weight);font-size:var(--md-sys-typescale-body-medium-font-size);letter-spacing:var(--md-sys-typescale-body-medium-tracking);line-height:var(--md-sys-typescale-body-medium-height);text-transform:var(--md-sys-typescale-body-medium-text-transform);-webkit-text-decoration:var(--md-sys-typescale-body-medium-text-decoration);text-decoration:var(--md-sys-typescale-body-medium-text-decoration)}.body-small{font-family:var(--md-sys-typescale-body-small-font-family-name);font-style:var(--md-sys-typescale-body-small-font-family-style);font-weight:var(--md-sys-typescale-body-small-font-weight);font-size:var(--md-sys-typescale-body-small-font-size);letter-spacing:var(--md-sys-typescale-body-small-tracking);line-height:var(--md-sys-typescale-body-small-height);text-transform:var(--md-sys-typescale-body-small-text-transform);-webkit-text-decoration:var(--md-sys-typescale-body-small-text-decoration);text-decoration:var(--md-sys-typescale-body-small-text-decoration)}.label-large{font-family:var(--md-sys-typescale-label-large-font-family-name);font-style:var(--md-sys-typescale-label-large-font-family-style);font-weight:var(--md-sys-typescale-label-large-font-weight);font-size:var(--md-sys-typescale-label-large-font-size);letter-spacing:var(--md-sys-typescale-label-large-tracking);line-height:var(--md-sys-typescale-label-large-height);text-transform:var(--md-sys-typescale-label-large-text-transform);-webkit-text-decoration:var(--md-sys-typescale-label-large-text-decoration);text-decoration:var(--md-sys-typescale-label-large-text-decoration)}.label-medium{font-family:var(--md-sys-typescale-label-medium-font-family-name);font-style:var(--md-sys-typescale-label-medium-font-family-style);font-weight:var(--md-sys-typescale-label-medium-font-weight);font-size:var(--md-sys-typescale-label-medium-font-size);letter-spacing:var(--md-sys-typescale-label-medium-tracking);line-height:var(--md-sys-typescale-label-medium-height);text-transform:var(--md-sys-typescale-label-medium-text-transform);-webkit-text-decoration:var(--md-sys-typescale-label-medium-text-decoration);text-decoration:var(--md-sys-typescale-label-medium-text-decoration)}.label-small{font-family:var(--md-sys-typescale-label-small-font-family-name);font-style:var(--md-sys-typescale-label-small-font-family-style);font-weight:var(--md-sys-typescale-label-small-font-weight);font-size:var(--md-sys-typescale-label-small-font-size);letter-spacing:var(--md-sys-typescale-label-small-tracking);line-height:var(--md-sys-typescale-label-small-height);text-transform:var(--md-sys-typescale-label-small-text-transform);-webkit-text-decoration:var(--md-sys-typescale-label-small-text-decoration);text-decoration:var(--md-sys-typescale-label-small-text-decoration)}.title-large{font-family:var(--md-sys-typescale-title-large-font-family-name);font-style:var(--md-sys-typescale-title-large-font-family-style);font-weight:var(--md-sys-typescale-title-large-font-weight);font-size:var(--md-sys-typescale-title-large-font-size);letter-spacing:var(--md-sys-typescale-title-large-tracking);line-height:var(--md-sys-typescale-title-large-height);text-transform:var(--md-sys-typescale-title-large-text-transform);-webkit-text-decoration:var(--md-sys-typescale-title-large-text-decoration);text-decoration:var(--md-sys-typescale-title-large-text-decoration)}.title-medium{font-family:var(--md-sys-typescale-title-medium-font-family-name);font-style:var(--md-sys-typescale-title-medium-font-family-style);font-weight:var(--md-sys-typescale-title-medium-font-weight);font-size:var(--md-sys-typescale-title-medium-font-size);letter-spacing:var(--md-sys-typescale-title-medium-tracking);line-height:var(--md-sys-typescale-title-medium-height);text-transform:var(--md-sys-typescale-title-medium-text-transform);-webkit-text-decoration:var(--md-sys-typescale-title-medium-text-decoration);text-decoration:var(--md-sys-typescale-title-medium-text-decoration)}.title-small{font-family:var(--md-sys-typescale-title-small-font-family-name);font-style:var(--md-sys-typescale-title-small-font-family-style);font-weight:var(--md-sys-typescale-title-small-font-weight);font-size:var(--md-sys-typescale-title-small-font-size);letter-spacing:var(--md-sys-typescale-title-small-tracking);line-height:var(--md-sys-typescale-title-small-height);text-transform:var(--md-sys-typescale-title-small-text-transform);-webkit-text-decoration:var(--md-sys-typescale-title-small-text-decoration);text-decoration:var(--md-sys-typescale-title-small-text-decoration)}.primary{background-color:var(--md-sys-color-primary)}.primary-text{color:var(--md-sys-color-primary)}.on-primary{background-color:var(--md-sys-color-on-primary)}.on-primary-text{color:var(--md-sys-color-on-primary)}.primary-container{background-color:var(--md-sys-color-primary-container)}.primary-container-text{color:var(--md-sys-color-primary-container)}.on-primary-container{background-color:var(--md-sys-color-on-primary-container)}.on-primary-container-text{color:var(--md-sys-color-on-primary-container)}.secondary{background-color:var(--md-sys-color-secondary)}.secondary-text{color:var(--md-sys-color-secondary)}.on-secondary{background-color:var(--md-sys-color-on-secondary)}.on-secondary-text{color:var(--md-sys-color-on-secondary)}.secondary-container{background-color:var(--md-sys-color-secondary-container)}.secondary-container-text{color:var(--md-sys-color-secondary-container)}.on-secondary-container{background-color:var(--md-sys-color-on-secondary-container)}.on-secondary-container-text{color:var(--md-sys-color-on-secondary-container)}.tertiary{background-color:var(--md-sys-color-tertiary)}.tertiary-text{color:var(--md-sys-color-tertiary)}.on-tertiary{background-color:var(--md-sys-color-on-tertiary)}.on-tertiary-text{color:var(--md-sys-color-on-tertiary)}.tertiary-container{background-color:var(--md-sys-color-tertiary-container)}.tertiary-container-text{color:var(--md-sys-color-tertiary-container)}.on-tertiary-container{background-color:var(--md-sys-color-on-tertiary-container)}.on-tertiary-container-text{color:var(--md-sys-color-on-tertiary-container)}.error{background-color:var(--md-sys-color-error)}.error-text{color:var(--md-sys-color-error)}.on-error{background-color:var(--md-sys-color-on-error)}.on-error-text{color:var(--md-sys-color-on-error)}.error-container{background-color:var(--md-sys-color-error-container)}.error-container-text{color:var(--md-sys-color-error-container)}.on-error-container{background-color:var(--md-sys-color-on-error-container)}.on-error-container-text{color:var(--md-sys-color-on-error-container)}.background{background-color:var(--md-sys-color-background)}.background-text{color:var(--md-sys-color-background)}.on-background{background-color:var(--md-sys-color-on-background)}.on-background-text{color:var(--md-sys-color-on-background)}.surface{background-color:var(--md-sys-color-surface)}.surface-text{color:var(--md-sys-color-surface)}.on-surface{background-color:var(--md-sys-color-on-surface)}.on-surface-text{color:var(--md-sys-color-on-surface)}.surface-variant{background-color:var(--md-sys-color-surface-variant)}.surface-variant-text{color:var(--md-sys-color-surface-variant)}.on-surface-variant{background-color:var(--md-sys-color-on-surface-variant)}.on-surface-variant-text{color:var(--md-sys-color-on-surface-variant)}.outline{background-color:var(--md-sys-color-outline)}.outline-text{color:var(--md-sys-color-outline)}.inverse-on-surface{background-color:var(--md-sys-color-inverse-on-surface)}.inverse-on-surface-text{color:var(--md-sys-color-inverse-on-surface)}.inverse-surface{background-color:var(--md-sys-color-inverse-surface)}.inverse-surface-text{color:var(--md-sys-color-inverse-surface)}.inverse-primary{background-color:var(--md-sys-color-inverse-primary)}.inverse-primary-text{color:var(--md-sys-color-inverse-primary)}.shadow{background-color:var(--md-sys-color-shadow)}.shadow-text{color:var(--md-sys-color-shadow)}.surface-tint{background-color:var(--md-sys-color-surface-tint)}.surface-tint-text{color:var(--md-sys-color-surface-tint)}.outline-variant{background-color:var(--md-sys-color-outline-variant)}.outline-variant-text{color:var(--md-sys-color-outline-variant)}.scrim{background-color:var(--md-sys-color-scrim)}.scrim-text{color:var(--md-sys-color-scrim)}a{text-decoration:none}html{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-weight:normal;color:var(--md-sys-color-on-background)}@media only screen and (min-width: 0){html{font-size:14px}}@media only screen and (min-width: 993px){html{font-size:14.5px}}@media only screen and (min-width: 1201px){html{font-size:15px}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.3}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:110%;margin:2.8rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:110%;margin:2.3733333333rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:110%;margin:1.9466666667rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:110%;margin:1.52rem 0 .912rem 0}h5{font-size:1.64rem;line-height:110%;margin:1.0933333333rem 0 .656rem 0}h6{font-size:1.15rem;line-height:110%;margin:.7666666667rem 0 .46rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light{font-weight:300}.thin{font-weight:200}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem}}@media only screen and (max-width: 360px){.flow-text{font-size:1.2rem}}html{-webkit-box-sizing:border-box;box-sizing:border-box}*,*:before,*:after{-webkit-box-sizing:inherit;box-sizing:inherit}body{background-color:var(--md-sys-color-background);color:var(--md-sys-color-on-background)}button,input,optgroup,select,textarea{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}a{color:colorFunc("light-blue", "darken-1");text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.valign-wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.clearfix{clear:both}.z-depth-0,.pagination li.active a:focus,.pagination li.disabled a,.btn.filled:focus,.btn.tonal:focus,.btn.text,.btn-flat,.btn.disabled,.btn-floating.disabled,.btn-large.disabled,.btn-small.disabled,.btn-flat.disabled,.btn:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-small:disabled,.btn-flat:disabled,.btn[disabled],.btn-floating[disabled],.btn-large[disabled],.btn-small[disabled],.btn-flat[disabled],.filled.btn-floating:focus,.tonal.btn-floating:focus,.text.btn-floating,.filled.btn-large:focus,.tonal.btn-large:focus,.text.btn-large,.filled.btn-small:focus,.tonal.btn-small:focus,.text.btn-small{-webkit-box-shadow:none !important;box-shadow:none !important}.z-depth-1,.sidenav,.dropdown-content,.collapsible,.pagination li.active a:hover,.card-panel,.card,.btn.filled:hover,.btn.tonal:hover,.btn.elevated,.btn.elevated:focus,.filled.btn-floating:hover,.tonal.btn-floating:hover,.elevated.btn-floating,.elevated.btn-floating:focus,.btn-floating,.filled.btn-large:hover,.tonal.btn-large:hover,.elevated.btn-large,.elevated.btn-large:focus,.filled.btn-small:hover,.tonal.btn-small:hover,.elevated.btn-small,.elevated.btn-small:focus{-webkit-box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.12),0 1px 5px 0 rgba(0,0,0,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.12),0 1px 5px 0 rgba(0,0,0,.2)}.z-depth-1-half,.btn-floating:hover,.btn-floating:focus{-webkit-box-shadow:0 3px 3px 0 rgba(0,0,0,.14),0 1px 7px 0 rgba(0,0,0,.12),0 3px 1px -1px rgba(0,0,0,.2);box-shadow:0 3px 3px 0 rgba(0,0,0,.14),0 1px 7px 0 rgba(0,0,0,.12),0 3px 1px -1px rgba(0,0,0,.2)}.z-depth-2,.btn.elevated:hover,.elevated.btn-floating:hover,.elevated.btn-large:hover,.elevated.btn-small:hover{-webkit-box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.3);box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.3)}.z-depth-3,.toast{-webkit-box-shadow:0 8px 17px 2px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2);box-shadow:0 8px 17px 2px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.z-depth-4{-webkit-box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -7px rgba(0,0,0,.2);box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -7px rgba(0,0,0,.2)}.z-depth-5,.modal{-webkit-box-shadow:0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12),0 11px 15px -7px rgba(0,0,0,.2);box-shadow:0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12),0 11px 15px -7px rgba(0,0,0,.2)}.hoverable{-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s}.hoverable:hover{-webkit-box-shadow:0 8px 17px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);box-shadow:0 8px 17px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19)}.divider{height:1px;overflow:hidden;background-color:var(--md-sys-color-outline-variant)}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid var(--md-sys-color-primary)}i{line-height:inherit}i.left{float:left;margin-left:-8px}i.right{float:right}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}html.noscroll{position:fixed;overflow-y:scroll;width:100%}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax-container .parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax-container .parallax img{opacity:0;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform:translateX(-50%);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}select:focus{outline:1px solid var(--md-ref-palette-primary80)}label{font-size:.8rem;color:var(--md-sys-color-on-surface-variant)}ul.staggered-list li{opacity:0}.fade-in{opacity:0;-webkit-transform-origin:0 50%;transform-origin:0 50%}@media only screen and (max-width : 600.99px){.hide-on-small-only,.hide-on-small-and-down{display:none !important}}@media only screen and (max-width : 992.99px){.hide-on-med-and-down{display:none !important}}@media only screen and (min-width : 601px){.hide-on-med-and-up{display:none !important}}@media only screen and (min-width: 601px)and (max-width: 992.99px){.hide-on-med-only{display:none !important}}@media only screen and (min-width : 993px){.hide-on-large-only{display:none !important}}@media only screen and (min-width : 1201px){.hide-on-extra-large-only{display:none !important}}@media only screen and (min-width : 1201px){.show-on-extra-large{display:block !important}}@media only screen and (min-width : 993px){.show-on-large{display:block !important}}@media only screen and (min-width: 601px)and (max-width: 992.99px){.show-on-medium{display:block !important}}@media only screen and (max-width : 600.99px){.show-on-small{display:block !important}}@media only screen and (min-width : 601px){.show-on-medium-and-up{display:block !important}}@media only screen and (max-width : 992.99px){.show-on-medium-and-down{display:block !important}}@media only screen and (max-width : 600.99px){.center-on-small-only{text-align:center}}.page-footer{margin-top:5rem;padding-top:3rem;border-top:1px dashed var(--md-sys-color-outline-variant)}.page-footer p{color:var(--md-sys-color-outline-light)}.page-footer a{color:var(--md-sys-color-primary)}.page-footer .footer-copyright,.page-footer .footer-copyright a{overflow:hidden;min-height:50px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:10px 0px}.page-footer ul{padding-left:0;list-style-type:none}table,th,td{border:none}table{width:100%;display:table;border-collapse:collapse;border-spacing:0}table.striped tr{border-bottom:none}table.striped tbody>tr:nth-child(odd){background-color:rgba(0,0,0,.08)}table.highlight>tbody>tr{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:rgba(0,0,0,.04)}table thead{color:var(--md-sys-color-on-surface-variant)}table.centered thead tr th,table.centered tbody tr td{text-align:center}tr{border-bottom:1px solid var(--md-sys-color-outline-variant)}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:0}@media only screen and (max-width : 992.99px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:" "}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:" "}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{border-bottom:none;padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid var(--md-sys-color-outline-variant)}}.video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.display-docked{position:absolute;opacity:0;z-index:9999;visibility:hidden}.confirmation-btns{margin-left:auto}.material-icons,.material-symbols-outlined,.material-symbols-rounded,.material-symbols-sharp{text-rendering:optimizeLegibility;-webkit-font-feature-settings:"liga";-moz-font-feature-settings:"liga";font-feature-settings:"liga"}.container{margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width : 601px){.container{width:85%}}@media only screen and (min-width : 993px){.container{width:70%}}.section{padding:1rem 0}body{--gap-size: 1.5rem}.row{display:grid;grid-template-columns:repeat(12, 1fr);gap:var(--gap-size)}.row .s1{grid-column:auto/span 1}.row .s2{grid-column:auto/span 2}.row .s3{grid-column:auto/span 3}.row .s4{grid-column:auto/span 4}.row .s5{grid-column:auto/span 5}.row .s6{grid-column:auto/span 6}.row .s7{grid-column:auto/span 7}.row .s8{grid-column:auto/span 8}.row .s9{grid-column:auto/span 9}.row .s10{grid-column:auto/span 10}.row .s11{grid-column:auto/span 11}.row .s12{grid-column:auto/span 12}.row .offset-s1{grid-column-start:3}.row .offset-s2{grid-column-start:2}.row .offset-s3{grid-column-start:4}.row .offset-s4{grid-column-start:5}.row .offset-s5{grid-column-start:6}.row .offset-s6{grid-column-start:7}.row .offset-s7{grid-column-start:8}.row .offset-s8{grid-column-start:9}.row .offset-s9{grid-column-start:10}.row .offset-s10{grid-column-start:11}.row .offset-s11{grid-column-start:12}@media only screen and (min-width : 601px){.row .m1{grid-column:auto/span 1}.row .m2{grid-column:auto/span 2}.row .m3{grid-column:auto/span 3}.row .m4{grid-column:auto/span 4}.row .m5{grid-column:auto/span 5}.row .m6{grid-column:auto/span 6}.row .m7{grid-column:auto/span 7}.row .m8{grid-column:auto/span 8}.row .m9{grid-column:auto/span 9}.row .m10{grid-column:auto/span 10}.row .m11{grid-column:auto/span 11}.row .m12{grid-column:auto/span 12}.row .offset-m1{grid-column-start:2}.row .offset-m2{grid-column-start:3}.row .offset-m3{grid-column-start:4}.row .offset-m4{grid-column-start:5}.row .offset-m5{grid-column-start:6}.row .offset-m6{grid-column-start:7}.row .offset-m7{grid-column-start:8}.row .offset-m8{grid-column-start:9}.row .offset-m9{grid-column-start:10}.row .offset-m10{grid-column-start:11}.row .offset-m11{grid-column-start:12}}@media only screen and (min-width : 993px){.row .l1{grid-column:auto/span 1}.row .l2{grid-column:auto/span 2}.row .l3{grid-column:auto/span 3}.row .l4{grid-column:auto/span 4}.row .l5{grid-column:auto/span 5}.row .l6{grid-column:auto/span 6}.row .l7{grid-column:auto/span 7}.row .l8{grid-column:auto/span 8}.row .l9{grid-column:auto/span 9}.row .l10{grid-column:auto/span 10}.row .l11{grid-column:auto/span 11}.row .l12{grid-column:auto/span 12}.row .offset-l1{grid-column-start:2}.row .offset-l2{grid-column-start:3}.row .offset-l3{grid-column-start:4}.row .offset-l4{grid-column-start:5}.row .offset-l5{grid-column-start:6}.row .offset-l6{grid-column-start:7}.row .offset-l7{grid-column-start:8}.row .offset-l8{grid-column-start:9}.row .offset-l9{grid-column-start:10}.row .offset-l10{grid-column-start:11}.row .offset-l11{grid-column-start:12}}@media only screen and (min-width : 1201px){.row .xl1{grid-column:auto/span 1}.row .xl2{grid-column:auto/span 2}.row .xl3{grid-column:auto/span 3}.row .xl4{grid-column:auto/span 4}.row .xl5{grid-column:auto/span 5}.row .xl6{grid-column:auto/span 6}.row .xl7{grid-column:auto/span 7}.row .xl8{grid-column:auto/span 8}.row .xl9{grid-column:auto/span 9}.row .xl10{grid-column:auto/span 10}.row .xl11{grid-column:auto/span 11}.row .xl12{grid-column:auto/span 12}.row .offset-xl1{grid-column-start:2}.row .offset-xl2{grid-column-start:3}.row .offset-xl3{grid-column-start:4}.row .offset-xl4{grid-column-start:5}.row .offset-xl5{grid-column-start:6}.row .offset-xl6{grid-column-start:7}.row .offset-xl7{grid-column-start:8}.row .offset-xl8{grid-column-start:9}.row .offset-xl9{grid-column-start:10}.row .offset-xl10{grid-column-start:11}.row .offset-xl11{grid-column-start:12}}.g-0{gap:0}.g-1{gap:calc(.25*var(--gap-size))}.g-2{gap:calc(.5*var(--gap-size))}.g-3{gap:calc(1*var(--gap-size))}.g-4{gap:calc(1.5*var(--gap-size))}.g-5{gap:calc(3*var(--gap-size))}.scale-transition{-webkit-transition:-webkit-transform .3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:-webkit-transform .3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform .3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform .3s cubic-bezier(0.53, 0.01, 0.36, 1.63), -webkit-transform .3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important}.scale-transition.scale-out{-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform .2s !important;transition:-webkit-transform .2s !important;transition:transform .2s !important;transition:transform .2s, -webkit-transform .2s !important}.scale-transition.scale-in{-webkit-transform:scale(1);transform:scale(1)}.pulse{overflow:visible;position:relative;&::before{content:"";display:block;position:absolute;pointer-events:none;width:100%;height:100%;top:0;left:0;background-color:inherit;border-radius:inherit;-webkit-transition:opacity .3s,-webkit-transform .3s;transition:opacity .3s,-webkit-transform .3s;transition:opacity .3s,transform .3s;transition:opacity .3s,transform .3s,-webkit-transform .3s;-webkit-animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;z-index:-1}}@-webkit-keyframes pulse-animation{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}}@keyframes pulse-animation{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}}.table-of-contents{list-style:none}.table-of-contents.fixed{position:fixed}.table-of-contents li{padding:0}.table-of-contents a{display:inline-block;font-weight:400;color:var(--md-sys-color-secondary);padding-left:16px;height:2rem;line-height:2rem;border-left:1px solid var(--md-sys-color-outline-variant)}.table-of-contents a:hover{color:var(--md-sys-color-on-background);padding-left:15px}.table-of-contents a.active{color:var(--md-sys-color-primary);font-weight:500;padding-left:14px;border-left:2px solid var(--md-sys-color-primary)}.tap-target-wrapper{width:800px;height:800px;position:fixed;z-index:1000;visibility:hidden;-webkit-transition:visibility 0s .3s;transition:visibility 0s .3s}.tap-target-wrapper.open{visibility:visible;-webkit-transition:visibility 0s;transition:visibility 0s}.tap-target-wrapper.open .tap-target{-webkit-transform:scale(1);transform:scale(1);opacity:.95;-webkit-transition:opacity .3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform .3s cubic-bezier(0.42, 0, 0.58, 1);transition:opacity .3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform .3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform .3s cubic-bezier(0.42, 0, 0.58, 1),opacity .3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform .3s cubic-bezier(0.42, 0, 0.58, 1),opacity .3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform .3s cubic-bezier(0.42, 0, 0.58, 1)}.tap-target-wrapper.open .tap-target-wave::before{-webkit-transform:scale(1);transform:scale(1)}.tap-target-wrapper.open .tap-target-wave::after{visibility:visible;-webkit-animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;-webkit-transition:opacity .3s,visibility 0s 1s,-webkit-transform .3s;transition:opacity .3s,visibility 0s 1s,-webkit-transform .3s;transition:opacity .3s,transform .3s,visibility 0s 1s;transition:opacity .3s,transform .3s,visibility 0s 1s,-webkit-transform .3s}.tap-target{position:absolute;font-size:1rem;border-radius:50%;background-color:var(--md-sys-color-primary-container);color:var(--md-sys-color-primary);-webkit-box-shadow:0 20px 20px 0 rgba(0,0,0,.14),0 10px 50px 0 rgba(0,0,0,.12),0 30px 10px -20px rgba(0,0,0,.2);box-shadow:0 20px 20px 0 rgba(0,0,0,.14),0 10px 50px 0 rgba(0,0,0,.12),0 30px 10px -20px rgba(0,0,0,.2);width:100%;height:100%;opacity:0;-webkit-transform:scale(0);transform:scale(0);-webkit-transition:opacity .3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform .3s cubic-bezier(0.42, 0, 0.58, 1);transition:opacity .3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform .3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform .3s cubic-bezier(0.42, 0, 0.58, 1),opacity .3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform .3s cubic-bezier(0.42, 0, 0.58, 1),opacity .3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform .3s cubic-bezier(0.42, 0, 0.58, 1)}.tap-target-content{position:relative;display:table-cell}.tap-target-wave{position:absolute;border-radius:50%;z-index:10001}.tap-target-wave::before,.tap-target-wave::after{content:"";display:block;position:absolute;width:100%;height:100%;border-radius:50%;background-color:var(--md-sys-color-surface)}.tap-target-wave::before{-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s}.tap-target-wave::after{visibility:hidden;-webkit-transition:opacity .3s,visibility 0s,-webkit-transform .3s;transition:opacity .3s,visibility 0s,-webkit-transform .3s;transition:opacity .3s,transform .3s,visibility 0s;transition:opacity .3s,transform .3s,visibility 0s,-webkit-transform .3s;z-index:-1}.tap-target-origin{top:50%;left:50%;z-index:10002;position:absolute !important;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%)}.tap-target-origin:not(.btn),.tap-target-origin:not(.btn):hover{background:none}@media only screen and (max-width: 600px){.tap-target,.tap-target-wrapper{width:600px;height:600px}}:root{--btn-height: 40px;--btn-font-size-icon: 16px;--btn-padding: 24px;--btn-padding-icon: 16px;--btn-gap-icon: 8px;--btn-border-radius: 4px;--btn-font-size: 14px}.btn,.btn-small,.btn-large,.btn-floating,.btn-flat{height:var(--btn-height);border-radius:var(--btn-border-radius);padding-left:var(--btn-padding);padding-right:var(--btn-padding);font-size:var(--btn-font-size);font-weight:500;text-decoration:none;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;border:none;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);white-space:nowrap;outline:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:background-color .2s ease-out;transition:background-color .2s ease-out}.btn:focus,.btn-floating:focus,.btn-large:focus,.btn-small:focus,.btn-flat:focus{background-color:var(--md-sys-color-primary-container)}.btn.icon-left,.icon-left.btn-small,.icon-left.btn-large,.icon-left.btn-floating,.btn.icon-right,.icon-right.btn-small,.icon-right.btn-large,.icon-right.btn-floating{position:relative}.btn.icon-left,.icon-left.btn-small,.icon-left.btn-large,.icon-left.btn-floating{padding-left:calc(var(--btn-padding-icon) + var(--btn-font-size-icon) + var(--btn-gap-icon))}.btn.icon-right,.icon-right.btn-small,.icon-right.btn-large,.icon-right.btn-floating{padding-right:calc(var(--btn-padding-icon) + var(--btn-font-size-icon) + var(--btn-gap-icon))}.btn.icon-left i,.icon-left.btn-small i,.icon-left.btn-large i,.icon-left.btn-floating i,.btn.icon-right i,.icon-right.btn-small i,.icon-right.btn-large i,.icon-right.btn-floating i{position:absolute;font-size:var(--btn-font-size-icon)}.btn.icon-left i,.icon-left.btn-small i,.icon-left.btn-large i,.icon-left.btn-floating i{left:var(--btn-padding-icon)}.btn.icon-right i,.icon-right.btn-small i,.icon-right.btn-large i,.icon-right.btn-floating i{right:var(--btn-padding-icon)}.btn.filled,.filled.btn-small,.filled.btn-large,.filled.btn-floating{color:var(--md-sys-color-on-primary);background-color:var(--md-sys-color-primary)}.btn.filled:hover,.filled.btn-small:hover,.filled.btn-large:hover,.filled.btn-floating:hover,.btn.filled:focus,.filled.btn-small:focus,.filled.btn-large:focus,.filled.btn-floating:focus{color:var(--md-sys-color-on-primary)}.btn.filled:hover,.filled.btn-small:hover,.filled.btn-large:hover,.filled.btn-floating:hover{background-color:color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 16%)}.btn.filled:focus,.filled.btn-small:focus,.filled.btn-large:focus,.filled.btn-floating:focus{background-color:color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 20%)}.btn.filled:focus-visible,.filled.btn-small:focus-visible,.filled.btn-large:focus-visible,.filled.btn-floating:focus-visible{outline:3px solid var(--md-sys-color-secondary);outline-offset:2px}.btn.tonal,.tonal.btn-small,.tonal.btn-large,.tonal.btn-floating{color:var(--md-sys-color-on-secondary-container);background-color:var(--md-sys-color-secondary-container)}.btn.tonal:hover,.tonal.btn-small:hover,.tonal.btn-large:hover,.tonal.btn-floating:hover,.btn.tonal:focus,.tonal.btn-small:focus,.tonal.btn-large:focus,.tonal.btn-floating:focus{color:var(--md-sys-color-on-secondary-container)}.btn.tonal:hover,.tonal.btn-small:hover,.tonal.btn-large:hover,.tonal.btn-floating:hover{background-color:color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-secondary-container) 16%)}.btn.tonal:focus,.tonal.btn-small:focus,.tonal.btn-large:focus,.tonal.btn-floating:focus{background-color:color-mix(in srgb, var(--md-sys-color-secondary-container), var(--md-sys-color-on-secondary-container) 20%)}.btn.tonal:focus-visible,.tonal.btn-small:focus-visible,.tonal.btn-large:focus-visible,.tonal.btn-floating:focus-visible{outline:3px solid var(--md-sys-color-secondary);outline-offset:2px}.btn.elevated:focus-visible,.elevated.btn-small:focus-visible,.elevated.btn-large:focus-visible,.elevated.btn-floating:focus-visible{outline:3px solid var(--md-sys-color-secondary);outline-offset:2px}.btn.outlined,.outlined.btn-small,.outlined.btn-large,.outlined.btn-floating{background-color:rgba(0,0,0,0);color:var(--md-sys-color-primary);border:1px solid var(--md-sys-color-outline)}.btn.outlined:hover,.outlined.btn-small:hover,.outlined.btn-large:hover,.outlined.btn-floating:hover,.btn.outlined:focus,.outlined.btn-small:focus,.outlined.btn-large:focus,.outlined.btn-floating:focus{color:var(--md-sys-color-primary)}.btn.outlined:hover,.outlined.btn-small:hover,.outlined.btn-large:hover,.outlined.btn-floating:hover{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 16%)}.btn.outlined:focus,.outlined.btn-small:focus,.outlined.btn-large:focus,.outlined.btn-floating:focus{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%);border:1px solid var(--md-sys-color-primary)}.btn.outlined.disabled,.outlined.disabled.btn-small,.outlined.disabled.btn-large,.outlined.disabled.btn-floating{background-color:unset;border-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}.btn.outlined:focus-visible,.outlined.btn-small:focus-visible,.outlined.btn-large:focus-visible,.outlined.btn-floating:focus-visible{outline:3px solid var(--md-sys-color-secondary);outline-offset:2px}.btn.text,.text.btn-small,.text.btn-large,.text.btn-floating,.btn-flat{color:var(--md-sys-color-primary);background-color:rgba(0,0,0,0)}.btn.text:hover,.text.btn-small:hover,.text.btn-large:hover,.text.btn-floating:hover,.btn.text:focus,.text.btn-small:focus,.text.btn-large:focus,.text.btn-floating:focus,.btn-flat:hover,.btn-flat:focus{color:var(--md-sys-color-primary)}.btn.text:hover,.text.btn-small:hover,.text.btn-large:hover,.text.btn-floating:hover,.btn-flat:hover{background-color:color-mix(in srgb, var(--md-sys-color-primary) 16%, transparent)}.btn.text:focus,.text.btn-small:focus,.text.btn-large:focus,.text.btn-floating:focus,.btn-flat:focus{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%)}.btn.text.disabled,.text.disabled.btn-small,.text.disabled.btn-large,.text.disabled.btn-floating,.btn-flat.disabled{background-color:unset}.btn.text:focus-visible,.text.btn-small:focus-visible,.text.btn-large:focus-visible,.text.btn-floating:focus-visible,.btn-flat:focus-visible{outline:3px solid var(--md-sys-color-secondary);outline-offset:2px}.btn.disabled,.btn-floating.disabled,.btn-large.disabled,.btn-small.disabled,.btn-flat.disabled,.btn:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-small:disabled,.btn-flat:disabled,.btn[disabled],.btn-floating[disabled],.btn-large[disabled],.btn-small[disabled],.btn-flat[disabled]{color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%);background-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%);pointer-events:none;-webkit-box-shadow:none;box-shadow:none;cursor:default}.btn-floating{width:40px;height:40px;color:var(--md-sys-color-on-primary-container);background-color:var(--md-sys-color-primary-container);border-radius:16px;padding:0;display:grid;grid-auto-flow:column;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:relative;overflow:hidden;z-index:1;-webkit-transition:background-color .3s;transition:background-color .3s;cursor:pointer;vertical-align:middle;text-align:center}.btn-floating:hover{background-color:color-mix(in srgb, var(--md-sys-color-primary-container), var(--md-sys-color-on-primary-container) 16%)}.btn-floating:focus{background-color:var(--md-ref-palette-secondary80)}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:56px;height:56px;padding:0}.btn-floating.btn-large.halfway-fab{bottom:-28px}.btn-floating.btn-small{--btn-small-height: calc(0.75 * var(--btn-height));width:var(--btn-small-height);height:var(--btn-small-height)}.btn-floating.btn-small.halfway-fab{bottom:calc(var(--btn-small-height)*-0.5)}.btn-floating.halfway-fab{position:absolute;right:24px;bottom:-20px}.btn-floating.halfway-fab.left{right:auto;left:24px}.btn-floating i{color:currentColor;font-size:1.6rem;width:inherit;display:inline-block;text-align:center}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:997}.fixed-action-btn.active ul{visibility:visible;padding-left:0;list-style-type:none}.fixed-action-btn.direction-left,.fixed-action-btn.direction-right{padding:0 0 0 15px}.fixed-action-btn.direction-left ul,.fixed-action-btn.direction-right ul{text-align:right;right:64px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);height:100%;left:auto;width:500px}.fixed-action-btn.direction-left ul li,.fixed-action-btn.direction-right ul li{display:inline-block;margin:7.5px 15px 0 0}.fixed-action-btn.direction-right{padding:0 15px 0 0}.fixed-action-btn.direction-right ul{text-align:left;direction:rtl;left:64px;right:auto}.fixed-action-btn.direction-right ul li{margin:7.5px 0 0 15px}.fixed-action-btn.direction-bottom{padding:0 0 15px 0}.fixed-action-btn.direction-bottom ul{top:64px;bottom:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.fixed-action-btn.direction-bottom ul li{margin:15px 0 0 0}.fixed-action-btn.toolbar{padding:0;height:56px}.fixed-action-btn.toolbar.active>a i{opacity:0}.fixed-action-btn.toolbar ul{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;top:0;bottom:0;z-index:1}.fixed-action-btn.toolbar ul li{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;display:inline-block;margin:0;height:100%;-webkit-transition:none;transition:none}.fixed-action-btn.toolbar ul li a{display:block;overflow:hidden;position:relative;width:100%;height:100%;background-color:rgba(0,0,0,0);-webkit-box-shadow:none;box-shadow:none;color:var(--md-sys-color-on-secondary);line-height:56px;z-index:1}.fixed-action-btn.toolbar ul li a i{line-height:inherit}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px;margin:0;visibility:hidden}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.fixed-action-btn .fab-backdrop{position:absolute;top:0;left:0;z-index:-1;width:40px;height:40px;background-color:var(--md-sys-color-secondary);border-radius:16px;-webkit-transform:scale(0);transform:scale(0)}.btn-large{height:calc(1.5*var(--btn-height));font-size:18px;padding:0 28px}.btn-large i{font-size:1.6rem}.btn-small{height:calc(.75*var(--btn-height));font-size:13px}.btn-small i{font-size:1.2rem}.btn-block{display:block}.btn.rounded,.rounded.btn-floating,.rounded.btn-large,.rounded.btn-small{border-radius:99999px}.collapsible{padding-left:0;list-style-type:none;border-top:1px solid var(--md-sys-color-outline-variant);border-right:1px solid var(--md-sys-color-outline-variant);border-left:1px solid var(--md-sys-color-outline-variant);margin:.5rem 0 1rem 0}.collapsible-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);line-height:1.5;padding:1rem;border-bottom:1px solid var(--md-sys-color-outline-variant)}.collapsible-header:focus{outline:0}.collapsible-header i{width:2rem;font-size:1.6rem;display:inline-block;text-align:center;margin-right:1rem}.collapsible-header::after{content:"";margin-left:.5rem;font-family:"Material Symbols Outlined","Material Symbols Rounded","Material Symbols Sharp","Material Icons";font-size:25px;line-height:.9;-webkit-font-smoothing:antialiased}.active .collapsible-header::after{content:""}.keyboard-focused .collapsible-header:focus{background-color:rgba(0,0,0,.12)}.collapsible-header-content{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.collapsible-body{max-height:0;border-bottom:1px solid var(--md-sys-color-outline-variant);-webkit-box-sizing:border-box;box-sizing:border-box;padding:0 2rem;overflow:hidden}.collapsible.popout{border:none;-webkit-box-shadow:none;box-shadow:none}.collapsible.popout>li{-webkit-box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);margin:0 24px;-webkit-transition:margin .35s cubic-bezier(0.25, 0.46, 0.45, 0.94);transition:margin .35s cubic-bezier(0.25, 0.46, 0.45, 0.94)}.collapsible.popout>li.active{-webkit-box-shadow:0 5px 11px 0 rgba(0,0,0,.18),0 4px 15px 0 rgba(0,0,0,.15);box-shadow:0 5px 11px 0 rgba(0,0,0,.18),0 4px 15px 0 rgba(0,0,0,.15);margin:16px 0}:root{--bagde-height: 22px}span.badge{min-width:3rem;padding:0 6px;margin-left:14px;text-align:center;font-size:1rem;line-height:var(--bagde-height);height:var(--bagde-height);color:var(--md-sys-color-on-surface-variant);float:right;-webkit-box-sizing:border-box;box-sizing:border-box}span.badge.new{font-weight:300;font-size:.8rem;color:var(--md-sys-color-on-primary);background-color:var(--md-sys-color-primary);border-radius:2px}span.badge.new:after{content:" new"}span.badge[data-badge-caption]::after{content:" " attr(data-badge-caption)}.active span.badge{color:var(--md-sys-color-on-primary)}.navbar ul a span.badge{display:inline-block;float:none;margin-left:4px;line-height:var(--bagde-height);height:var(--bagde-height);-webkit-font-smoothing:auto}.collection-item span.badge{margin-top:calc(.75rem - var(--bagde-height)*.5)}.collapsible span.badge{margin-left:auto}.collapsible span.badge.leading{margin-right:7px;-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.collapsible .active span.badge:not(.new){color:var(--md-sys-color-on-surface-variant)}.sidenav span.badge{margin-top:calc(var(--sidenav-line-height)*.5 - 11px)}table span.badge{display:inline-block;float:none;margin-left:auto}.card-panel{-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s;padding:24px;margin:.5rem 0 1rem 0;border-radius:12px;background-color:var(--md-sys-color-surface)}.card{--background-color: color-mix(in srgb, var(--md-sys-color-surface), var(--md-sys-color-surface-tint) 17%);position:relative;background-color:var(--background-color);-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s;border-radius:12px}.card .card-title{font-size:24px;font-weight:300}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{max-height:60%;overflow:hidden}.card.small .card-image+.card-content,.card.medium .card-image+.card-content,.card.large .card-image+.card-content{max-height:40%}.card.small .card-content,.card.medium .card-content,.card.large .card-content{max-height:100%;overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.medium{height:400px}.card.large{height:500px}.card.horizontal{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.card.horizontal.small .card-image,.card.horizontal.medium .card-image,.card.horizontal.large .card-image{height:100%;max-height:none;overflow:visible}.card.horizontal.small .card-image img,.card.horizontal.medium .card-image img,.card.horizontal.large .card-image img{height:100%}.card.horizontal .card-image{max-width:50%}.card.horizontal .card-image img{border-radius:2px 0 0 2px;max-width:100%;width:auto}.card.horizontal .card-stacked{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;position:relative}.card.horizontal .card-stacked .card-content{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.card.sticky-action .card-action{z-index:2}.card.sticky-action .card-reveal{z-index:1;padding-bottom:64px}.card .card-image{position:relative}.card .card-image img{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{color:var(--md-sys-color-surface);position:absolute;bottom:0;left:0;max-width:100%;padding:24px}.card .card-image .activator{position:absolute;left:0;right:0;top:0;bottom:0;cursor:pointer}.card .card-image img.activator{position:relative}.card .card-content{padding:24px;border-radius:0 0 2px 2px}.card .card-content p{margin:0}.card .card-content .card-title{display:block;line-height:32px;margin-bottom:8px}.card .card-content .card-title i{line-height:32px}.card .card-content .card-title.activator{cursor:pointer}.card .card-action{padding:0 1.6rem}.card .card-action:last-child{border-radius:0 0 2px 2px}.card .card-action a{height:var(--btn-height);border-radius:var(--btn-border-radius);padding-left:var(--btn-padding);padding-right:var(--btn-padding);font-size:var(--btn-font-size);font-weight:500;text-decoration:none;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;border:none;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);white-space:nowrap;outline:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:background-color .2s ease-out;transition:background-color .2s ease-out}.card .card-action a:focus{background-color:var(--md-sys-color-primary-container)}.card .card-action a:first-child{margin-left:-1.6rem}.card .card-action a:last-child{margin-right:-1.6rem}.card .card-action .btn.filled,.card .card-action .btn.tonal,.card .card-action .btn.elevated,.card .card-action .btn.outlined{margin:0 .26rem 1.6rem 0}.card .card-reveal{padding:24px;position:absolute;background-color:var(--md-sys-color-surface);width:100%;overflow-y:auto;left:0;top:100%;height:100%;z-index:3;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:10000}@media only screen and (max-width : 600.99px){#toast-container{min-width:100%;bottom:0%}}@media only screen and (min-width : 601px)and (max-width : 992.99px){#toast-container{left:5%;bottom:7%;max-width:90%}}@media only screen and (min-width : 993px){#toast-container{top:10%;right:7%;max-width:86%}}.toast{border-radius:4px;top:35px;width:auto;margin-top:10px;position:relative;max-width:100%;height:auto;min-height:48px;padding-left:16px;padding-right:12px;font-size:14px;font-weight:500;line-height:20px;color:var(--md-sys-color-inverse-on-surface);background-color:var(--md-sys-color-inverse-surface);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;cursor:default}.toast .toast-action{color:var(--md-sys-color-inverse-primary);font-weight:500;margin-right:-25px;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width : 600.99px){.toast{width:100%;border-radius:0}}.tabs{padding-left:0;list-style-type:none;position:relative;overflow-x:auto;overflow-y:hidden;width:100%;background-color:var(--md-sys-color-surface);margin:0 auto;white-space:nowrap;scrollbar-width:none}.tabs.tabs-transparent{background-color:rgba(0,0,0,0)}.tabs.tabs-transparent .tab a{color:var(--font-on-primary-color-medium)}.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover,.tabs.tabs-transparent .tab.disabled a:focus{color:hsla(0,0%,100%,.38)}.tabs.tabs-transparent .tab a:hover{background-color:rgba(0,0,0,.04)}.tabs.tabs-transparent .tab a.active,.tabs.tabs-transparent .tab a:focus{background-color:rgba(0,0,0,0)}.tabs.tabs-transparent .tab a:hover,.tabs.tabs-transparent .tab a.active,.tabs.tabs-transparent .tab a:focus{color:var(--md-sys-color-on-primary)}.tabs.tabs-transparent .indicator{background-color:var(--md-sys-color-on-primary)}.tabs.tabs-fixed-width{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs.tabs-fixed-width .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab{padding-left:0;list-style-type:none;display:inline-block;text-align:center;line-height:48px;padding:0;margin:0}.tabs .tab i.material-icons{position:relative;top:8px;vertical-align:middle}.tabs .tab span{height:24px;line-height:20px}.tabs .tab a{color:var(--md-sys-color-on-surface-variant);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;height:100%;min-height:48px;padding:0 24px;font-size:14px;text-overflow:ellipsis;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;-webkit-transition:color .28s ease,background-color .28s ease;transition:color .28s ease,background-color .28s ease}.tabs .tab a.active{background-color:rgba(0,0,0,0)}.tabs .tab a.active,.tabs .tab a:focus,.tabs .tab a:hover{color:var(--md-sys-color-primary)}.tabs .tab a:hover{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%)}.tabs .tab a:focus{background-color:var(--md-sys-color-primary-container)}.tabs .tab a.active{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%)}.tabs .tab a:focus,.tabs .tab a.active{outline:none}.tabs .tab.disabled a,.tabs .tab.disabled a:hover{color:var(--md-sys-color-on-surface);cursor:default;background-color:rgba(0,0,0,0)}.tabs .tab.disabled a:not(:focus),.tabs .tab.disabled a:hover:not(:focus){background-color:rgba(0,0,0,0)}.tabs .indicator{position:absolute;bottom:0;height:3px;background-color:var(--md-sys-color-primary);will-change:left,right;border-radius:3px 3px 0 0}.tabs.tabs-horizontal .tab{height:48px}.tabs.tabs-horizontal .tab a{display:block}.tabs.tabs-horizontal .tab i.material-icons{padding:0 4px;position:relative;top:-2px;vertical-align:middle}@media only screen and (max-width : 992.99px){.tabs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab a{padding:0 12px}}.material-tooltip{padding:0 8px;border-radius:4px;color:var(--md-sys-color-inverse-on-surface);background-color:var(--md-sys-color-inverse-surface);font-family:var(--md-sys-typescale-body-small-font-family-name);font-size:var(--md-sys-typescale-body-small-font-size);line-height:var(--md-sys-typescale-body-small-line-height);font-weight:var(--md-sys-typescale-body-small-font-weight);min-height:24px;opacity:0;padding-top:6px;padding-bottom:6px;font-size:12px;line-height:16px;font-weight:400;letter-spacing:.4px;position:absolute;max-width:300px;overflow:hidden;left:0;top:0;pointer-events:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;visibility:hidden;z-index:2000}.backdrop{position:absolute;opacity:0;height:7px;width:14px;border-radius:0 0 50% 50%;background-color:var(--md-sys-color-inverse-surface);z-index:-1;-webkit-transform-origin:50% 0;transform-origin:50% 0;visibility:hidden}[popover]{outline:none;padding:0;border:none}.dropdown-content{padding-left:0;list-style-type:none;background-color:var(--md-sys-color-surface);margin:0;display:none;min-width:100px;overflow-y:auto;opacity:0;position:absolute;left:0;top:0;z-index:9999;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap}.dropdown-content li{clear:both;color:var(--md-sys-color-on-background);cursor:pointer;min-height:50px;line-height:1.5rem;width:100%;text-align:left}.dropdown-content li.divider{min-height:0;height:1px}.dropdown-content li>a,.dropdown-content li>span{font-size:16px;color:var(--md-sys-color-primary);display:block;line-height:22px;padding:14px 16px}.dropdown-content li>span>label{top:1px;left:0;height:18px}.dropdown-content li>a>i{height:inherit;line-height:inherit;float:left;margin:0 24px 0 0;width:24px}.dropdown-content li:not(.disabled):hover,.dropdown-content li.active{background-color:color-mix(in srgb, var(--md-sys-color-surface), var(--md-sys-color-on-surface) 8%)}body.keyboard-focused .dropdown-content li:focus{background-color:rgba(0,0,0,.12)}.input-field.col .dropdown-content [type=checkbox]+label{top:1px;left:0;height:18px;-webkit-transform:none;transform:none}.dropdown-trigger{cursor:pointer}.collection{padding-left:0;list-style-type:none;margin:.5rem 0 1rem 0;border:1px solid var(--md-sys-color-outline-variant);border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:rgba(0,0,0,0);line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid var(--md-sys-color-outline-variant)}.collection .collection-item.avatar{min-height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar:not(.circle-clipper)>.circle,.collection .collection-item.avatar :not(.circle-clipper)>.circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:var(--md-sys-color-shadow-light);text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.collection .collection-item.active .secondary-content{color:var(--md-sys-color-on-primary)}.collection a.collection-item{display:block;-webkit-transition:.25s;transition:.25s;color:var(--md-sys-color-primary)}.collection a.collection-item:not(.active):hover{background-color:rgba(0,0,0,.04)}.collection.with-header .collection-header{background-color:rgba(0,0,0,0);border-bottom:1px solid var(--md-sys-color-outline-variant);padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.collection.with-header .collection-item.avatar{padding-left:72px}.secondary-content{float:right;color:var(--md-sys-color-primary)}.collapsible .collection{margin:0;border:none}.list-item{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.modal{--modal-footer-divider-height: 1px;--modal-border-radius: 28px;--modal-padding: 24px;--modal-padding-bottom: 16px;--modal-background-color: color-mix(in srgb, var(--md-sys-color-surface), var(--md-sys-color-surface-tint) 17%);border:none;outline:none;padding:0;max-height:70%;width:55%;border-radius:var(--modal-border-radius);will-change:top,opacity;background-color:var(--modal-background-color)}.modal[open]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}@media only screen and (max-width : 992.99px){.modal{width:80%}}.modal::-webkit-backdrop{-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}.modal::-ms-backdrop{backdrop-filter:blur(1px)}.modal::backdrop{-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}.modal .modal-header{padding:var(--modal-padding);padding-bottom:var(--modal-padding-bottom);-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;position:-webkit-sticky;position:sticky;top:0}.modal .modal-content{padding:0 var(--modal-padding)}.modal .modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;border-radius:0 0 var(--modal-border-radius) var(--modal-border-radius);padding:var(--modal-padding);text-align:right;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;position:-webkit-sticky;position:sticky;bottom:0;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.modal .modal-close{cursor:pointer}.modal h1,.modal h2,.modal h3,.modal h4,.modal h5,.modal h6{margin:0}.modal.bottom-sheet{margin-bottom:0;max-height:45%;border-bottom-left-radius:0;border-bottom-right-radius:0;will-change:bottom,opacity}.materialboxed{display:block;cursor:-webkit-zoom-in;cursor:zoom-in;position:relative;-webkit-transition:opacity .4s;transition:opacity .4s;-webkit-backface-visibility:hidden}.materialboxed:hover:not(.active){opacity:.8}.materialboxed.active{cursor:-webkit-zoom-out;cursor:zoom-out}#materialbox-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background-color:var(--md-sys-color-background);z-index:1000;will-change:opacity}.materialbox-caption{position:fixed;display:none;color:var(--md-sys-color-on-background);line-height:50px;bottom:0;left:0;width:100%;text-align:center;padding:0% 15%;height:50px;z-index:1000;-webkit-font-smoothing:antialiased}.chip{--font-size: 14px;--font-size-icon: 18px;--padding: 8px;color:var(--md-sys-color-on-surface-variant);background-color:rgba(0, 0, 0, 0.09);display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;white-space:nowrap;gap:8px;margin:0;height:32px;padding-left:var(--padding);padding-right:var(--padding);font-size:var(--font-size);font-weight:500;border-radius:8px;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top}.chip:focus{outline:none;background-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.chip.outlined{background-color:transparent;border-color:var(--md-sys-color-outline);border-width:1px;border-style:solid}.chip>img{margin:0;width:24px;height:24px;-o-object-fit:cover;object-fit:cover;border-radius:12px}.chip>.material-icons{font-size:var(--font-size-icon);color:var(--md-sys-color-on-surface-variant)}.chip .close{border:none;border-radius:50%;height:24px;width:24px;padding:0;display:grid;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;cursor:pointer}.chip .close:hover{background-color:rgba(136,136,136,.5333333333)}.chips{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:4px;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;border:none;-webkit-box-shadow:none;box-shadow:none;margin:0 0 8px 0;padding:4px;outline:none;-webkit-transition:all .3s;transition:all .3s}.chips.focus{border-bottom:1px solid var(--md-sys-color-primary);-webkit-box-shadow:0 1px 0 0 var(--md-sys-color-primary);box-shadow:0 1px 0 0 var(--md-sys-color-primary)}.chips.input-field{border-bottom:1px solid var(--md-sys-color-on-surface-variant)}.chis input:not([type]):not(.browser-default).input{background:none;border:0;color:var(--md-sys-color-on-background);display:inline-block;font-size:16px;height:32px;outline:0;margin:0;padding:0;width:120px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;min-width:100px;max-width:200px}.chis input:not([type]):not(.browser-default).input:focus{border:0;-webkit-box-shadow:none;box-shadow:none}.chips.input-field:hover{cursor:text}.chips .autocomplete-content{margin-top:0;margin-bottom:0}.prefix~.chips{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.suffix~.chips{margin-right:3rem;width:92%;width:calc(100% - 3rem)}.chips:empty~label{font-size:.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}:root{--navbar-height: 64px;--navbar-height-mobile: 56px;--appbar-title-font-size: 24px}.nav-wrapper{height:100%;background-color:var(--md-sys-color-surface);padding-left:4px;padding-right:4px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar{color:var(--md-sys-color-on-surface);height:var(--navbar-height-mobile)}.navbar ul:not(.dropdown-content){list-style-type:none;margin:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;gap:1em}.navbar ul:not(.dropdown-content)>li{-webkit-transition:background-color .3s;transition:background-color .3s;padding:0}.navbar ul:not(.dropdown-content)>li>a{-webkit-transition:background-color .3s;transition:background-color .3s;color:var(--md-sys-color-on-surface);display:block;cursor:pointer}.navbar .brand-logo{color:var(--md-sys-color-on-surface);font-size:var(--appbar-title-font-size);display:inline-block;padding:0}.navbar .nav-title{display:inline-block;font-size:32px;padding:28px 0}.navbar-fixed{position:fixed;z-index:997}.sidenav{--sidenav-width: 300px;--sidenav-font-size: 14px;--sidenav-padding: 16px;--sidenav-item-height: 48px;--sidenav-line-height: var(--sidenav-item-height);position:fixed;width:var(--sidenav-width);left:0;top:0;margin:0;-webkit-transform:translateX(-100%);transform:translateX(-100%);height:100vh;padding:0;z-index:999;overflow-y:auto;will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateX(-105%);transform:translateX(-105%);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:var(--md-sys-color-on-secondary-container);background-color:var(--md-sys-color-surface)}.sidenav.right-aligned{right:0;-webkit-transform:translateX(105%);transform:translateX(105%);left:auto;-webkit-transform:translateX(100%);transform:translateX(100%)}.sidenav .collapsible{margin:0}.sidenav a:focus{background-color:rgba(0,0,0,.12)}.sidenav li.active>a:not(.collapsible-header):not(.btn):not(.btn-large):not(.btn-small):not(.btn-flat):not(.btn-large):not(.btn-floating){background-color:color-mix(in srgb, var(--md-sys-color-secondary) 10%, transparent)}.sidenav .collapsible-body>ul{padding-left:10px}.sidenav li{list-style:none;display:grid;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center}.sidenav li>a{margin:0 12px;padding:0 var(--sidenav-padding);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:var(--sidenav-item-height);font-size:var(--sidenav-font-size);font-weight:500;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;overflow:hidden;border-radius:100px}.sidenav li>a:not(.btn):not(.btn-flat):not(.btn-large):not(.btn-floating){color:var(--md-sys-color-on-secondary-container)}.sidenav li>a:not(.btn):not(.btn-flat):not(.btn-large):not(.btn-floating):hover{background-color:color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent)}.sidenav li>a.btn,.sidenav li>a.btn-large,.sidenav li>a.btn-flat,.sidenav li>a.btn-floating{margin:10px 15px}.sidenav li>a>.material-icons,.sidenav li>a>.material-symbols-outlined,.sidenav li>a>.material-symbols-rounded,.sidenav li>a>.material-symbols-sharp{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle;margin-right:12px}.sidenav .divider{margin:calc(var(--sidenav-padding)*.5) 0 0 0}.sidenav .subheader{cursor:initial;pointer-events:none;color:red;font-size:var(--sidenav-font-size);font-weight:500;line-height:var(--sidenav-line-height)}.sidenav .user-view{position:relative;padding:calc(var(--sidenav-padding)*2) calc(var(--sidenav-padding)*2) 0;margin-bottom:calc(var(--sidenav-padding)*.5)}.sidenav .user-view>a{height:auto;padding:0}.sidenav .user-view>a:hover{background-color:rgba(0,0,0,0)}.sidenav .user-view .background{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1}.sidenav .user-view .circle,.sidenav .user-view .name,.sidenav .user-view .email{display:block}.sidenav .user-view .circle{height:64px;width:64px}.sidenav .user-view .name,.sidenav .user-view .email{font-size:var(--sidenav-font-size);line-height:calc(var(--sidenav-line-height)*.5)}.sidenav .user-view .name{margin-top:16px;font-weight:500}.sidenav .user-view .email{padding-bottom:16px;font-weight:400}.drag-target{height:100%;position:fixed;top:0;left:0;z-index:998}.drag-target.right-aligned{right:0}.sidenav.sidenav-fixed{left:0;-webkit-transform:translateX(0);transform:translateX(0);position:fixed}.sidenav.sidenav-fixed.right-aligned{right:0;left:auto}@media only screen and (max-width : 992.99px){.sidenav.sidenav-fixed{-webkit-transform:translateX(-105%);transform:translateX(-105%)}.sidenav.sidenav-fixed.right-aligned{-webkit-transform:translateX(105%);transform:translateX(105%)}.sidenav>a{padding:0 var(--sidenav-padding)}.sidenav .user-view{padding:var(--sidenav-padding) var(--sidenav-padding) 0}}.sidenav .collapsible-body{padding:0}.sidenav-overlay{position:fixed;top:0;left:0;right:0;opacity:0;height:120vh;background-color:rgba(0,0,0,.5);z-index:997;display:none}.sidenav .collapsible,.sidenav.sidenav-fixed .collapsible{border:none;-webkit-box-shadow:none;box-shadow:none}.sidenav .collapsible-header,.sidenav.sidenav-fixed .collapsible-header{border:none}.sidenav .collapsible-body,.sidenav.sidenav-fixed .collapsible-body{border:none}.progress{position:relative;height:4px;display:block;width:100%;background-color:var(--md-sys-color-surface-variant);border-radius:4px;margin:.5rem 0 1rem 0;overflow:hidden;background-color:var(--md-sys-color-secondary-container)}.progress .determinate{position:absolute;top:0;left:0;bottom:0;background-color:var(--md-sys-color-primary);-webkit-transition:width .3s linear;transition:width .3s linear}.progress .indeterminate{background-color:var(--md-sys-color-primary)}.progress .indeterminate:before{content:"";position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left,right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:"";position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left,right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.preloader-wrapper{display:inline-block;position:relative;width:50px;height:50px}.preloader-wrapper.small{width:36px;height:36px}.preloader-wrapper.big{width:64px;height:64px}.preloader-wrapper.active{-webkit-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg)}}@keyframes container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-layer{position:absolute;width:100%;height:100%;opacity:0;border-color:var(--md-sys-color-primary)}.spinner-blue,.spinner-blue-only{border-color:#4285f4}.spinner-red,.spinner-red-only{border-color:#db4437}.spinner-yellow,.spinner-yellow-only{border-color:#f4b400}.spinner-green,.spinner-green-only{border-color:#0f9d58}.active .spinner-layer.spinner-blue{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-red{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-yellow{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-green{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer,.active .spinner-layer.spinner-blue-only,.active .spinner-layer.spinner-red-only,.active .spinner-layer.spinner-yellow-only,.active .spinner-layer.spinner-green-only{opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg)}}@keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@-webkit-keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@-webkit-keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@-webkit-keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}@keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.gap-patch .circle{width:1000%;left:-450%}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:rgba(0,0,0,0) !important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0}.circle-clipper.left .circle{left:0;border-right-color:rgba(0,0,0,0) !important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.circle-clipper.right .circle{left:-100%;border-left-color:rgba(0,0,0,0) !important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.active .circle-clipper.left .circle{-webkit-animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .circle-clipper.right .circle{-webkit-animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg)}}@keyframes left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg)}}@keyframes right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}#spinnerContainer.cooldown{-webkit-animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1);animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1)}@-webkit-keyframes fade-out{from{opacity:1}to{opacity:0}}@keyframes fade-out{from{opacity:1}to{opacity:0}}.slider{position:relative;height:400px;width:100%}.slider.fullscreen{height:100%;width:100%;position:absolute;top:0;left:0;right:0;bottom:0}.slider.fullscreen ul.slides{padding-left:0;list-style-type:none;height:100%}.slider.fullscreen ul.indicators{padding-left:0;list-style-type:none;z-index:2;bottom:30px}.slider.fullscreen ul.indicators .indicator-item{background-color:hsla(0,0%,100%,.45)}.slider.fullscreen ul.indicators .indicator-item.active{background-color:var(--md-ref-palette-primary100)}.slider .slides{background-color:var(--md-sys-color-surface);margin:0;height:400px;padding-left:0;list-style-type:none}.slider .slides li{padding-left:0;list-style-type:none;opacity:0;position:absolute;top:0;left:0;z-index:1;width:100%;height:inherit;overflow:hidden}.slider .slides li img{height:100%;width:100%;background-size:cover;background-position:center}.slider .slides li .caption{color:#fff;position:absolute;top:15%;left:15%;width:70%;opacity:0}.slider .slides li .caption p{color:hsla(0,0%,100%,.75)}.slider .slides li.active{z-index:2}.slider .indicators{padding-left:0;list-style-type:none;position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.slider .indicators .indicator-item{display:inline-block;position:relative;height:16px;width:16px;margin:0 12px}.slider .indicators .indicator-item-btn{position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;background-color:var(--md-sys-color-shadow-light);-webkit-transition:background-color .3s;transition:background-color .3s;border-radius:50%;border-width:0}.slider .indicators .indicator-item-btn.active{background-color:var(--md-sys-color-primary)}.carousel{--carousel-height: 400px;overflow:hidden;position:relative;width:100%;height:var(--carousel-height);-webkit-perspective:500px;perspective:500px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform-origin:0% 50%;transform-origin:0% 50%}.carousel.carousel-slider{top:0;left:0}.carousel.carousel-slider .carousel-fixed-item{position:absolute;left:0;right:0;bottom:20px;z-index:1}.carousel.carousel-slider .carousel-fixed-item.with-indicators{bottom:68px}.carousel.carousel-slider .carousel-item{width:100%;height:100%;min-height:var(--carousel-height);position:absolute;top:0;left:0}.carousel.carousel-slider .carousel-item h2{font-size:24px;font-weight:500;line-height:32px}.carousel.carousel-slider .carousel-item p{font-size:15px}.carousel .carousel-item{visibility:hidden;width:calc(var(--carousel-height)*.5);height:calc(var(--carousel-height)*.5);position:absolute;top:0;left:0}.carousel .carousel-item>img{width:100%}.carousel .indicators{padding-left:0;list-style-type:none;position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.carousel .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:8px;width:8px;margin:24px 4px;background-color:hsla(0,0%,100%,.45);-webkit-transition:background-color .3s;transition:background-color .3s;border-radius:50%}.carousel .indicators .indicator-item.active{background-color:var(--md-ref-palette-primary100)}.carousel.scrolling .carousel-item .materialboxed,.carousel .carousel-item:not(.active) .materialboxed{pointer-events:none}.datepicker-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-width:325px;padding:0;background-color:var(--md-sys-color-inverse-on-surface)}.datepicker-controls{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;width:280px;margin:0 auto}.datepicker-controls .selects-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.datepicker-controls .select-wrapper input{height:49px;margin:4px 0 0 0;border-bottom:none;border-radius:4px;text-align:center}.datepicker-controls .select-wrapper input:focus{color:var(--md-sys-color-primary);background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%)}.datepicker-controls .select-wrapper input::-moz-selection{background-color:rgba(0,0,0,0)}.datepicker-controls .select-wrapper input::selection{background-color:rgba(0,0,0,0)}.datepicker-controls .select-wrapper .caret{display:none}.datepicker-controls .select-dropdown{padding:0;vertical-align:middle}.datepicker-controls .select-year input,.datepicker-controls .select-month input{background-color:rgba(0,0,0,0)}.datepicker-controls .select-year input{width:50px}.datepicker-controls .select-month input{width:80px}.datepicker-controls .month-prev,.datepicker-controls .month-next{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:49px;border-radius:var(--btn-border-radius);padding-left:var(--btn-padding);padding-right:var(--btn-padding);font-size:var(--btn-font-size);font-weight:500;text-decoration:none;display:inline-flex;align-items:center;border:none;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);white-space:nowrap;outline:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:background-color .2s ease-out;transition:background-color .2s ease-out}.datepicker-controls .month-prev:focus,.datepicker-controls .month-next:focus{background-color:var(--md-sys-color-primary-container)}.datepicker-controls .month-prev:focus,.datepicker-controls .month-next:focus{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 20%)}.datepicker-controls .month-prev>svg,.datepicker-controls .month-next>svg{fill:var(--md-sys-color-on-surface-variant)}.month-prev,.month-next{height:49px;margin-top:4px;cursor:pointer;background-color:rgba(0,0,0,0);border:none}.datepicker-date-display{-webkit-box-flex:1;-webkit-flex:1 auto;-ms-flex:1 auto;flex:1 auto;padding:20px 22px;border-bottom:1px solid var(--md-sys-color-surface-variant-light);font-weight:500}.datepicker-date-display .year-text{display:block;font-size:1.5rem;line-height:25px;color:var(--md-sys-color-on-primary)}.datepicker-date-display .date-text{display:block;font-size:2.8rem;line-height:47px;font-weight:500}.daterange .datepicker-date-display .date-text{font-size:1.8rem}.datepicker-calendar-container{-webkit-box-flex:2.5;-webkit-flex:2.5 auto;-ms-flex:2.5 auto;flex:2.5 auto}.datepicker-table{width:280px;font-size:1rem;margin:0 auto}.datepicker-table thead{border-bottom:none}.datepicker-table th{padding:10px 5px;text-align:center}.datepicker-table tr{border:none}.datepicker-table abbr{text-decoration:none;color:var(--md-sys-color-on-surface-variant)}.datepicker-table .datepicker-day{padding:0;color:var(--md-sys-color-on-background)}.datepicker-table .datepicker-day.is-today{color:var(--md-sys-color-primary)}.datepicker-day.is-daterange-start,.datepicker-day.is-daterange-end,.datepicker-day.is-daterange{position:relative}.datepicker-day.is-daterange-start:before,.datepicker-day.is-daterange-end:before,.datepicker-day.is-daterange:before{position:absolute;top:5px;width:100%;height:34px;content:"";background-color:var(--md-sys-color-primary-container);z-index:0}.datepicker-day.is-daterange-start:before,.datepicker-day.is-daterange-end:before{width:50%}.datepicker-day.is-daterange-start:before{left:50%}.datepicker-day.is-daterange .datepicker-day-button:before{background-color:var(--md-sys-color-primary-container)}.datepicker-day-button{background-color:rgba(0,0,0,0);border:none;line-height:34px;display:block;width:34px;border-radius:50%;margin:5px;padding:0 5px;cursor:pointer;color:inherit;position:relative;z-index:1}.datepicker-day-button:hover{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%)}.datepicker-day-button:focus{border-color:var(--md-sys-color-primary)}.is-selected .datepicker-day-button{background-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.is-selected .datepicker-day-button:focus{background-color:var(--md-sys-color-surface-variant);color:var(--md-sys-color-primary)}.datepicker-day-button.is-outside-current-month button,.datepicker-day-button.is-disabled button{color:var(--md-sys-color-on-surface);pointer-events:none}.datepicker-footer{width:280px;margin:0 auto;padding-bottom:5px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.datepicker-cancel,.datepicker-clear,.datepicker-today,.datepicker-done{color:var(--md-sys-color-primary);padding:0 1rem}.datepicker-clear{color:var(--md-sys-color-error)}.datepicker-modal{max-width:calc(325px + var(--modal-padding)*2);max-height:none;background-color:var(--md-sys-color-inverse-on-surface)}.timepicker-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-width:325px;padding:0;background-color:var(--md-sys-color-inverse-on-surface)}.text-primary{color:var(--md-sys-color-on-primary)}.timepicker-digital-display{width:auto;-webkit-box-flex:1;-webkit-flex:1 auto;-ms-flex:1 auto;flex:1 auto;padding:2rem .71rem .67rem .71rem;font-weight:300}.timepicker-text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:4rem;text-align:left;color:var(--font-on-primary-color-medium);font-weight:400;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:1rem 1rem 1.3rem 1rem}.timepicker-text-container input[type=text]{height:4rem;color:var(--md-sys-color-secondary);border-bottom:0px;font-size:4rem;direction:ltr}.timepicker-display-column{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex}.timepicker-display-digital-clock{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex}.timepicker-input-hours-wrapper,.timepicker-input-minutes-wrapper{width:6.85rem;height:5.75rem}.timepicker-input-hours,.timepicker-input-minutes,.timepicker-span-am-pm div{cursor:pointer}input[type=text].timepicker-input-hours,input[type=text].timepicker-input-minutes{height:100%;padding:1.33rem .8rem;border:0;text-align:center;color:var(--md-sys-color-on-background);background-color:var(--md-sys-color-surface-variant)}input[type=text].timepicker-input-hours:focus,input[type=text].timepicker-input-minutes:focus{background-color:var(--md-sys-color-primary-container)}.timepicker-input-divider-wrapper{width:1.6rem;text-align:center}.timepicker-display-am-pm{font-size:1.3rem;font-weight:400}.timepicker-span-am-pm{height:5.75rem;max-width:3.5rem}.timepicker-container .am-btn,.timepicker-container .pm-btn{width:3.6rem;height:50%;padding-left:calc(var(--btn-padding)/1.8);padding-right:calc(var(--btn-padding)/1.8);line-height:2rem;vertical-align:middle;text-align:center;border:1px solid var(--md-sys-color-outline)}.timepicker-container .am-btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.timepicker-container .pm-btn{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.timepicker-analog-display{-webkit-box-flex:2.5;-webkit-flex:2.5 auto;-ms-flex:2.5 auto;flex:2.5 auto;padding:.67rem}.timepicker-plate{background-color:var(--md-sys-color-surface-variant);border-radius:50%;width:260px;height:260px;overflow:visible;position:relative;margin:0 1.6rem 1.6rem 1.6rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.timepicker-canvas,.timepicker-dial{position:absolute;left:0;right:0;top:0;bottom:0}.timepicker-minutes{visibility:hidden}.timepicker-tick{border-radius:50%;color:var(--md-sys-color-on-background);line-height:40px;text-align:center;width:40px;height:40px;position:absolute;cursor:pointer;font-size:15px}.timepicker-tick.active,.timepicker-tick:hover{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%)}.timepicker-dial{-webkit-transition:opacity 350ms,-webkit-transform 350ms;transition:opacity 350ms,-webkit-transform 350ms;transition:transform 350ms,opacity 350ms;transition:transform 350ms,opacity 350ms,-webkit-transform 350ms}.timepicker-dial-out{opacity:0}.timepicker-dial-out.timepicker-hours{-webkit-transform:scale(1.1, 1.1);transform:scale(1.1, 1.1)}.timepicker-dial-out.timepicker-minutes{-webkit-transform:scale(0.8, 0.8);transform:scale(0.8, 0.8)}.timepicker-canvas{-webkit-transition:opacity 175ms;transition:opacity 175ms}.timepicker-canvas line{stroke:var(--md-sys-color-primary);stroke-width:4;stroke-linecap:round}.timepicker-canvas-out{opacity:.25}.timepicker-canvas-bearing{stroke:none;fill:var(--md-sys-color-primary)}.timepicker-canvas-bg{stroke:none;fill:var(--md-sys-color-primary)}.timepicker-footer{margin:0 auto;padding:5px 1rem;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.timepicker-clear{color:var(--md-sys-color-error)}.timepicker-close{color:var(--md-sys-color-primary)}.timepicker-clear,.timepicker-close{padding:0 20px}.timepicker-modal{max-width:326px;max-height:none;background-color:var(--md-sys-color-inverse-on-surface);overflow-x:hidden}.timepicker-modal .timepicker-container{margin-left:calc(-1*var(--modal-padding));margin-right:calc(-1*var(--modal-padding))}.timepicker-modal .modal-header+.modal-content .timepicker-digital-display{padding-top:0}.timepicker-modal .modal-header+.modal-content .timepicker-text-container{padding-top:4px}.timepicker-modal .timepicker-analog-display{padding-bottom:0}.timepicker-modal .timepicker-plate{margin-bottom:0}@media only screen and (min-width : 993px){.timepicker-container{width:auto;max-width:620px}.timepicker-container{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.timepicker-digital-display{padding:.67rem}.timepicker-text-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin-top:4.8rem;text-align:center}.timepicker-display-column{padding:0 3%}.timepicker-display-am-pm{margin-top:1.1rem}.timepicker-span-am-pm{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;max-width:unset}.timepicker-container .am-btn,.timepicker-container .pm-btn{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding-left:calc(var(--btn-padding)/.565);padding-right:calc(var(--btn-padding)/.565);border-radius:var(--btn-border-radius);border:1px solid var(--md-sys-color-outline)}.timepicker-container .am-btn{border-top-right-radius:0;border-bottom-right-radius:0}.timepicker-container .pm-btn{border-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.timepicker-plate{margin-top:1.6rem}.timepicker-modal{width:65%;max-width:605px}.timepicker-modal .modal-header+.modal-content .timepicker-digital-display,.timepicker-modal .modal-header+.modal-content .timepicker-analog-display{padding-top:0}.timepicker-modal .modal-header+.modal-content .timepicker-text-container{margin-top:2.4rem}.timepicker-modal .modal-header+.modal-content .timepicker-plate{margin-top:4px;margin-bottom:0}.timepicker-modal .timepicker-digital-display,.timepicker-modal .timepicker-analog-display{padding-bottom:0}.timepicker-modal .timepicker-plate{margin-bottom:0}}.breadcrumb-wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.breadcrumb{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.breadcrumb i,.breadcrumb i.material-icons,.breadcrumb i.material-symbols-outlined,.breadcrumb i.material-symbols-rounded,.breadcrumb i.material-symbols-sharp,.breadcrumb:before{font-weight:normal;font-style:normal;font-size:24px}.breadcrumb:before{content:"";font-family:"Material Symbols Outlined","Material Symbols Rounded","Material Symbols Sharp","Material Icons"}.breadcrumb:first-child:before{visibility:hidden}.pagination li{display:inline-block;vertical-align:top}.pagination li a{height:2rem;border-radius:var(--btn-border-radius);padding-left:.66rem;padding-right:.66rem;font-size:1.2rem;font-weight:500;text-decoration:none;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;border:none;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);white-space:nowrap;outline:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:background-color .2s ease-out;transition:background-color .2s ease-out}.pagination li a:focus{background-color:var(--md-sys-color-primary-container)}.pagination li.active a{color:var(--md-sys-color-on-primary);background-color:var(--md-sys-color-primary)}.pagination li.active a:hover,.pagination li.active a:focus{color:var(--md-sys-color-on-primary)}.pagination li.active a:hover{background-color:color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 16%)}.pagination li.active a:focus{background-color:color-mix(in srgb, var(--md-sys-color-primary), var(--md-sys-color-on-primary) 20%)}.pagination li.active a:focus-visible{outline:3px solid var(--md-sys-color-secondary);outline-offset:2px}.pagination li.disabled a{color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%);background-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%);pointer-events:none;-webkit-box-shadow:none;box-shadow:none;cursor:default}.pagination li i{font-size:2rem}.pagination li.pages ul li{display:inline-block;float:none}@media only screen and (max-width : 992.99px){.pagination{width:100%}.pagination li.prev,.pagination li.next{width:10%}.pagination li.pages{width:80%;overflow:hidden;white-space:nowrap}}[type=radio]:not(:checked),[type=radio]:checked{position:absolute;opacity:0;pointer-events:none}[type=radio]:not(:checked)+span,[type=radio]:checked+span{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-transition:.28s ease;transition:.28s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[type=radio]+span:before,[type=radio]+span:after{content:"";position:absolute;left:0;top:0;margin:4px;width:16px;height:16px;z-index:0;-webkit-transition:.28s ease;transition:.28s ease}[type=radio]:not(:checked)+span:before,[type=radio]:not(:checked)+span:after,[type=radio]:checked+span:before,[type=radio]:checked+span:after,[type=radio].with-gap:checked+span:before,[type=radio].with-gap:checked+span:after{border-radius:50%}[type=radio]:not(:checked)+span:before,[type=radio]:not(:checked)+span:after{border:2px solid var(--md-sys-color-on-surface-variant)}[type=radio]:not(:checked)+span:after{-webkit-transform:scale(0);transform:scale(0)}[type=radio]:checked+span:before{border:2px solid rgba(0,0,0,0)}[type=radio]:checked+span:after,[type=radio].with-gap:checked+span:before,[type=radio].with-gap:checked+span:after{border:2px solid var(--md-sys-color-primary)}[type=radio]:checked+span:after,[type=radio].with-gap:checked+span:after{background-color:var(--md-sys-color-primary)}[type=radio]:checked+span:after{-webkit-transform:scale(1.02);transform:scale(1.02)}[type=radio].with-gap:checked+span:after{-webkit-transform:scale(0.5);transform:scale(0.5)}[type=radio].tabbed:focus+span:before{-webkit-box-shadow:0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%);box-shadow:0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%)}[type=radio].with-gap:disabled:checked+span:before{border:2px solid color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}[type=radio].with-gap:disabled:checked+span:after{border:none;background-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}[type=radio]:disabled:not(:checked)+span:before,[type=radio]:disabled:checked+span:before{background-color:rgba(0,0,0,0);border-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}[type=radio]:disabled+span{color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}[type=radio]:disabled:not(:checked)+span:before{border-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}[type=radio]:disabled:checked+span:after{background-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%);border-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}:root{--checkbox-size: 18px;--checkbox-shape: 2px}input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;position:relative;cursor:pointer}input[type=checkbox]:focus{outline:3px solid var(--md-sys-color-secondary);border-radius:50%;outline-offset:.5rem}input[type=checkbox]:before{opacity:1;position:absolute;display:block;width:var(--checkbox-size);height:var(--checkbox-size);border:2px solid var(--md-sys-color-on-surface-variant);border-radius:var(--checkbox-shape);content:""}input[type=checkbox]:after{position:relative;display:block;width:var(--checkbox-size);height:var(--checkbox-size);content:"";border-radius:var(--checkbox-shape);background-repeat:no-repeat;background-position:center}input[type=checkbox]:checked:after{background-color:var(--md-sys-color-primary);-webkit-clip-path:polygon(0 48%, 0 0, 56% 0, 74% 17%, 40% 64%, 23% 50%, 14% 61%, 42% 82%, 81% 31%, 32% 0, 100% 0, 100% 100%, 0 100%, 0 49%);clip-path:polygon(0 48%, 0 0, 56% 0, 74% 17%, 40% 64%, 23% 50%, 14% 61%, 42% 82%, 81% 31%, 32% 0, 100% 0, 100% 100%, 0 100%, 0 49%)}[type=checkbox]:indeterminate:after{background-color:var(--md-sys-color-primary);-webkit-clip-path:polygon(0% 0%, 0% 100%, 18% 100%, 16% 43%, 83% 42%, 83% 63%, 16% 63%, 16% 100%, 100% 100%, 100% 0%);clip-path:polygon(0% 0%, 0% 100%, 18% 100%, 16% 43%, 83% 42%, 83% 63%, 16% 63%, 16% 100%, 100% 100%, 100% 0%)}input[type=checkbox]:disabled:before{-webkit-filter:opacity(0.2);filter:opacity(0.2)}input[type=checkbox]:disabled:after{-webkit-filter:opacity(0.2);filter:opacity(0.2)}input[type=checkbox]:not(:disabled):checked:hover:after{background-color:var(--md-sys-color-primary)}input[type=checkbox]:not(:disabled):hover:after{border-color:#85a9bb #92c2da #92c2da #85a9bb}input[type=checkbox]:not(:disabled):hover:before{border-color:#3d7591}.switch{--track-height: 32px;--track-width: 52px;--border-width: 2px;--size-off: 16px;--size-on: 24px;--icon-size: 16px;--gap-on: calc(((var(--track-height) - var(--size-on)) / 2) - var(--border-width));--gap-off: calc(((var(--track-height) - var(--size-off)) / 2) - var(--border-width))}.switch,.switch *{-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch label{cursor:pointer}.switch label input[type=checkbox]{opacity:0;width:0;height:0}.switch label input[type=checkbox]:checked+.lever{background-color:var(--md-sys-color-primary);border-color:var(--md-sys-color-primary)}.switch label input[type=checkbox]:checked+.lever:before,.switch label input[type=checkbox]:checked+.lever:after{top:var(--gap-on);left:calc(var(--track-width) - var(--size-on) - var(--gap-on) - 2*var(--border-width));width:var(--size-on);height:var(--size-on)}.switch label input[type=checkbox]:checked+.lever:after{background-color:var(--md-sys-color-surface)}.switch label .lever{content:"";display:inline-block;position:relative;width:var(--track-width);height:var(--track-height);border-style:solid;border-width:2px;border-color:var(--md-sys-color-outline);background-color:var(--md-sys-color-surface-variant);border-radius:15px;margin-right:10px;-webkit-transition:background .3s ease;transition:background .3s ease;vertical-align:middle;margin:0 16px}.switch label .lever:before,.switch label .lever:after{content:"";position:absolute;display:inline-block;width:var(--size-off);height:var(--size-off);border-radius:50%;left:var(--gap-off);top:var(--gap-off);-webkit-transition:left .3s ease,background .3s ease,-webkit-box-shadow .1s ease,-webkit-transform .1s ease;transition:left .3s ease,background .3s ease,-webkit-box-shadow .1s ease,-webkit-transform .1s ease;transition:left .3s ease,background .3s ease,box-shadow .1s ease,transform .1s ease;transition:left .3s ease,background .3s ease,box-shadow .1s ease,transform .1s ease,-webkit-box-shadow .1s ease,-webkit-transform .1s ease}.switch label .lever:after{background-color:var(--md-sys-color-outline);height:var(--size-off);width:var(--size-off)}input[type=checkbox]:not(:disabled)~.lever:active:before,input[type=checkbox]:not(:disabled).tabbed:focus~.lever::before,input[type=checkbox]:not(:disabled)~.lever:hover::before{-webkit-transform:scale(2.4);transform:scale(2.4)}input[type=checkbox]:checked:not(:disabled)~.lever:hover::before{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 6%)}input[type=checkbox]:checked:not(:disabled)~.lever:active::before,input[type=checkbox]:checked:not(:disabled).tabbed:focus~.lever::before{background-color:color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%)}input[type=checkbox]:not(:disabled)~.lever:hover::before{background-color:rgba(0,0,0,.04)}input[type=checkbox]:not(:disabled)~.lever:active:before,input[type=checkbox]:not(:disabled).tabbed:focus~.lever::before{background-color:rgba(0,0,0,.12)}.switch input[type=checkbox][disabled]+.lever{cursor:default;opacity:.5}.range-field{position:relative}input[type=range],input[type=range]+.thumb{cursor:pointer}input[type=range]{position:relative;background:linear-gradient(var(--md-sys-color-outline-variant), var(--md-sys-color-outline-variant));border:none;outline:none;width:100%;margin:15px 0;padding:0;height:3px}input[type=range]:focus{outline:none}input[type=range]+.thumb{position:absolute;top:10px;left:0;border:none;height:0;width:0;border-radius:50%;background-color:var(--md-sys-color-primary);margin-left:7px;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}input[type=range]+.thumb .value{display:block;width:30px;text-align:center;color:var(--md-sys-color-primary);font-size:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}input[type=range]+.thumb.active{border-radius:50% 50% 50% 0}input[type=range]+.thumb.active .value{color:var(--md-sys-color-on-primary);margin-left:-1px;margin-top:8px;font-size:10px}input[type=range]{-moz-appearance:none;appearance:none;-webkit-appearance:none}input[type=range]::-webkit-slider-runnable-track{height:3px;background-color:var(--md-sys-color-surface-variant);border:none}input[type=range]::-webkit-slider-thumb{border:none;height:14px;width:14px;border-radius:50%;background:var(--md-sys-color-primary);-webkit-transition:-webkit-box-shadow .3s;transition:-webkit-box-shadow .3s;transition:box-shadow .3s;transition:box-shadow .3s, -webkit-box-shadow .3s;-webkit-appearance:none;background-color:var(--md-sys-color-primary);-webkit-transform-origin:50% 50%;transform-origin:50% 50%;margin:-5px 0 0 0}.keyboard-focused input[type=range]:focus:not(.active)::-webkit-slider-thumb{-webkit-box-shadow:0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%);box-shadow:0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%)}input[type=range]::-moz-range-track{height:3px;background-color:var(--md-sys-color-surface-variant);border:none}input[type=range]::-moz-focus-inner{border:0}input[type=range]::-moz-range-thumb{border:none;height:14px;width:14px;border-radius:50%;background:var(--md-sys-color-primary);-moz-transition:box-shadow .3s;transition:box-shadow .3s;margin-top:-5px}input[type=range]:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}.keyboard-focused input[type=range]:focus:not(.active)::-moz-range-thumb{box-shadow:0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%)}input[type=range]::-ms-track{height:3px;background:rgba(0,0,0,0);border-color:rgba(0,0,0,0);border-width:6px 0;color:rgba(0,0,0,0)}input[type=range]::-ms-fill-lower,input[type=range]::-moz-range-progress{background:var(--md-sys-color-primary)}input[type=range]::-ms-fill-upper,input[type=range]::-moz-range-track{background:var(--md-sys-color-shadow-light)}input[type=range]::-ms-thumb{border:none;height:14px;width:14px;border-radius:50%;background:var(--md-sys-color-primary);-ms-transition:box-shadow .3s;transition:box-shadow .3s}.keyboard-focused input[type=range]:focus:not(.active)::-ms-thumb{box-shadow:0 0 0 10px color-mix(in srgb, transparent, var(--md-sys-color-primary) 18%)}::-webkit-input-placeholder{color:var(--md-sys-color-on-surface-variant)}::-moz-placeholder{color:var(--md-sys-color-on-surface-variant)}:-ms-input-placeholder{color:var(--md-sys-color-on-surface-variant)}::-ms-input-placeholder{color:var(--md-sys-color-on-surface-variant)}::placeholder{color:var(--md-sys-color-on-surface-variant)}.input-field input.invalid,.input-field textarea.invalid{border-bottom:2px solid var(--md-sys-color-error);-webkit-box-shadow:0 1px 0 0 var(--md-sys-color-error);box-shadow:0 1px 0 0 var(--md-sys-color-error)}.input-field input.invalid~.supporting-text[data-error]>span,.input-field textarea.invalid~.supporting-text[data-error]>span{display:none}.input-field input.invalid~.supporting-text:after,.input-field textarea.invalid~.supporting-text:after{content:attr(data-error);color:var(--md-sys-color-error)}.input-field{--input-color: var(--md-sys-color-primary);position:relative;clear:both}.input-field input,.input-field textarea{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0 16px;padding-top:20px;border:none;border-radius:4px;border-bottom:1px solid var(--md-sys-color-on-surface-variant);border-bottom-left-radius:0;border-bottom-right-radius:0}.input-field input:focus:not([readonly]),.input-field textarea:focus:not([readonly]){border-bottom:2px solid var(--input-color);padding-top:21px}.input-field input:disabled,.input-field input[readonly=readonly],.input-field textarea:disabled,.input-field textarea[readonly=readonly]{color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%);border-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%);background-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 4%)}.input-field input:focus:not([readonly])+label,.input-field textarea:focus:not([readonly])+label{color:var(--input-color)}.input-field input:not(:-moz-placeholder)+label, .input-field textarea:not(:-moz-placeholder)+label{transform:scale(0.75);top:8px}.input-field input:not(:-ms-input-placeholder)+label, .input-field textarea:not(:-ms-input-placeholder)+label{transform:scale(0.75);top:8px}.input-field input:focus:not([readonly])+label,.input-field input:not([placeholder=" "])+label,.input-field input:not(:placeholder-shown)+label,.input-field textarea:focus:not([readonly])+label,.input-field textarea:not([placeholder=" "])+label,.input-field textarea:not(:placeholder-shown)+label{-webkit-transform:scale(0.75);transform:scale(0.75);top:8px}.input-field input:disabled+label,.input-field input[readonly=readonly]+label,.input-field textarea:disabled+label,.input-field textarea[readonly=readonly]+label{color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%)}.input-field input.invalid~label,.input-field input:focus.invalid~label,.input-field textarea.invalid~label,.input-field textarea:focus.invalid~label{color:var(--md-sys-color-error)}.input-field input::-webkit-input-placeholder{-webkit-user-select:none;user-select:none}.input-field input::-moz-placeholder{-moz-user-select:none;user-select:none}.input-field input:-ms-input-placeholder{-ms-user-select:none;user-select:none}.input-field input::-ms-input-placeholder{-ms-user-select:none;user-select:none}.input-field input::placeholder{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.input-field>label{color:var(--md-sys-color-on-surface-variant);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:16px;position:absolute;left:16px;top:16px;cursor:text;-webkit-transform-origin:top left;transform-origin:top left;-webkit-transition:left .2s ease-out,top .2s ease-out,-webkit-transform .2s ease-out;transition:left .2s ease-out,top .2s ease-out,-webkit-transform .2s ease-out;transition:left .2s ease-out,top .2s ease-out,transform .2s ease-out;transition:left .2s ease-out,top .2s ease-out,transform .2s ease-out,-webkit-transform .2s ease-out}.input-field .supporting-text{color:var(--md-sys-color-on-surface-variant);font-size:12px;padding:0 16px;margin-top:4px}.input-field .character-counter{color:var(--md-sys-color-on-surface-variant);font-size:12px;float:right;padding:0 16px;margin-top:4px}.input-field .prefix{position:absolute;left:12px;top:16px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.input-field .suffix{position:absolute;right:12px;top:16px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.input-field .prefix~input,.input-field .prefix~textarea{padding-left:52px}.input-field .suffix~input,.input-field .suffix~textarea{padding-right:52px}.input-field .prefix~label{left:52px}.input-field.outlined input,.input-field.outlined textarea{padding-top:0;background-color:rgba(0,0,0,0);border:1px solid var(--md-sys-color-on-surface-variant);border-radius:4px}.input-field.outlined input:focus:not([readonly]),.input-field.outlined textarea:focus:not([readonly]){border:2px solid var(--input-color);padding-top:0;margin-left:-1px}.input-field.outlined input:focus:not([readonly])+label,.input-field.outlined textarea:focus:not([readonly])+label{color:var(--input-color)}.input-field.outlined input:not(:-moz-placeholder)+label, .input-field.outlined textarea:not(:-moz-placeholder)+label{top:-8px;left:16px;margin-left:-4px;padding:0 4px;background-color:rgba(0,0,0,0)}.input-field.outlined input:not(:-ms-input-placeholder)+label, .input-field.outlined textarea:not(:-ms-input-placeholder)+label{top:-8px;left:16px;margin-left:-4px;padding:0 4px;background-color:rgba(0,0,0,0)}.input-field.outlined input:focus:not([readonly])+label,.input-field.outlined input:not([placeholder=" "])+label,.input-field.outlined input:not(:placeholder-shown)+label,.input-field.outlined textarea:focus:not([readonly])+label,.input-field.outlined textarea:not([placeholder=" "])+label,.input-field.outlined textarea:not(:placeholder-shown)+label{top:-8px;left:16px;margin-left:-4px;padding:0 4px;background-color:rgba(0,0,0,0)}.input-field.outlined input:disabled,.input-field.outlined input[readonly=readonly],.input-field.outlined textarea:disabled,.input-field.outlined textarea[readonly=readonly]{color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 38%);border-color:color-mix(in srgb, transparent, var(--md-sys-color-on-surface) 12%)}.input-field.error input,.input-field.error textarea{border-color:var(--md-sys-color-error)}.input-field.error input:focus:not([readonly]),.input-field.error textarea:focus:not([readonly]){border-color:var(--md-sys-color-error)}.input-field.error input:focus:not([readonly])+label,.input-field.error textarea:focus:not([readonly])+label{color:var(--md-sys-color-error)}.input-field.error label{color:var(--md-sys-color-error)}.input-field.error .supporting-text{color:var(--md-sys-color-error)}.input-field.error .suffix{color:var(--md-sys-color-error)}.inline{display:inline-block}.searchbar .prefix{position:absolute;padding-left:1rem;top:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.searchbar>input{border-width:0;background-color:rgba(0,0,0,0);padding-left:3rem}.searchbar.has-sidebar{margin-left:0}@media only screen and (min-width : 993px){.searchbar.has-sidebar{margin-left:300px}}textarea{width:100%;height:3rem;background-color:rgba(0,0,0,0)}textarea.materialize-textarea{padding-top:26px !important;padding-bottom:4px !important;line-height:normal;overflow-y:hidden;resize:none;min-height:3rem;-webkit-box-sizing:border-box;box-sizing:border-box}.hiddendiv{visibility:hidden;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;padding-top:1.2rem;position:absolute;top:0;z-index:-1}.autocomplete-content li .highlight{color:var(--md-sys-color-on-background)}.autocomplete-content li img{height:40px;width:40px;margin:5px 15px}.datepicker-date-input{position:relative;text-indent:-9999px}.datepicker-date-input::after{display:block;position:absolute;top:1.1rem;content:attr(data-date);color:var(--input-color);text-indent:0}.datepicker-date-input:focus-visible{text-indent:0}.datepicker-date-input:focus-visible:after{text-indent:-9999px}select.browser-default{opacity:1;color:var(--md-sys-color-on-background)}select{background-color:var(--md-sys-color-surface);width:100%;padding:5px;border:1px solid var(--md-sys-color-outline-variant);border-radius:2px;height:3rem}.select-wrapper:focus-within{outline:2px solid var(--md-sys-color-primary);border-radius:4px}.select-wrapper{position:relative}.select-wrapper .caret{position:absolute;right:0;top:0;bottom:0;margin:auto 0;z-index:0;fill:var(--md-sys-color-on-background);pointer-events:none}.select-wrapper .hide-select{width:0;height:0;overflow:hidden;position:absolute;top:0;z-index:-1}select:disabled{color:var(--md-sys-color-on-surface)}.select-wrapper.disabled+label{color:var(--md-sys-color-on-surface)}.select-wrapper.disabled .caret{fill:var(--md-sys-color-on-surface)}.select-wrapper input.select-dropdown:disabled{color:var(--md-sys-color-on-surface);cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select-wrapper i{color:var(--md-sys-color-on-surface)}.select-dropdown li.disabled,.select-dropdown li.disabled>span,.select-dropdown li.optgroup{color:var(--md-sys-color-on-surface)}.select-dropdown li img{height:40px;width:40px;margin:5px 15px;-o-object-fit:cover;object-fit:cover;float:right}.select-dropdown li.optgroup{border-top:1px solid rgba(0,0,0,.04)}.select-dropdown li.optgroup.selected>span{color:var(--md-sys-color-on-background)}.select-dropdown li.optgroup>span{color:var(--md-sys-color-on-surface-variant)}.select-dropdown li.optgroup~li.optgroup-option{padding-left:1rem}.file-field{display:grid;grid-template-columns:-webkit-min-content auto;grid-template-columns:min-content auto;gap:10px}.file-field .file-path-wrapper{overflow:hidden}.file-field input.file-path{width:100%}.file-field .btn{height:3rem;line-height:3rem}.file-field span{cursor:pointer}.file-field input[type=file]{position:absolute;top:0;right:0;left:0;bottom:0;cursor:pointer;width:100%;margin:0;padding:0;opacity:0;font-size:20px;filter:alpha(opacity=0)}.file-field input[type=file]::-webkit-file-upload-button{display:none}:root{--mw-font-size: 16px;--mw-border-radius: 8px;--mw-input-height: 56px;--mw-idle-color: var(--md-sys-color-outline);--mw-border-width: 1px;--mw-hover-color: var(--md-sys-color-on-primary-container);--mw-hover-border-width: 1px;--mw-focus-color: var(--md-sys-color-primary);--mw-focus-border-width: 2px;--mw-disabled-color: #8886;--mw-padding-left: 16px;--mw-input-padding-x: var(--mw-padding-left);--mw-input-padding-r: 12px;--mw-label-padding: 4px;--mw-inputlabel-duration: 0.2s;--mw-inset: 5px;--label-size: calc(var(--mw-font-size) * 0.75);--label-margin-left: calc(var(--mw-padding-left) - var(--mw-label-padding));--half-inp: calc((-0.5 * var(--mw-input-height)));--half-lbl: calc((0.5 * var(--label-size)));--distY: calc(var(--half-inp) + var(--half-lbl))}fieldset.form-field{position:relative;border-width:var(--mw-border-width);border-color:var(--mw-idle-color);border-style:solid;border-radius:var(--mw-border-radius);cursor:text;height:var(--mw-input-height);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:0;margin:0;display:grid;grid-auto-flow:column;-webkit-box-align:baseline;-webkit-align-items:baseline;-ms-flex-align:baseline;align-items:baseline;font-size:var(--mw-font-size);padding:0 calc(var(--mw-inset) - var(--mw-border-width))}fieldset.form-field legend{color:var(--mw-idle-color);font-size:var(--label-size);padding:0 var(--mw-label-padding);margin:0;margin-left:calc(var(--mw-padding-left) - var(--mw-label-padding) - var(--mw-border-width));cursor:text;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}fieldset.form-field input,fieldset.form-field select{--mw-calc-input-height: calc( var(--mw-input-height) - var(--label-size) + 2 * var(--mw-border-width) );-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--mw-font-size);padding:0;margin:0;width:100%;height:var(--mw-calc-input-height);max-height:var(--mw-calc-input-height);margin-top:calc(-1*var(--half-lbl));padding-left:calc(var(--mw-padding-left) - var(--mw-border-width));border:none;line-height:normal;outline:none;background:none}fieldset.form-field select{padding:0;padding-left:calc(var(--mw-padding-left) - var(--mw-label-padding));z-index:2}fieldset.form-field select option{background-color:black;color:white}fieldset.form-field input::-webkit-input-placeholder{color:var(--mw-idle-color);font-size:var(--mw-font-size)}fieldset.form-field input::-moz-placeholder{color:var(--mw-idle-color);font-size:var(--mw-font-size)}fieldset.form-field input:-ms-input-placeholder{color:var(--mw-idle-color);font-size:var(--mw-font-size)}fieldset.form-field input::-ms-input-placeholder{color:var(--mw-idle-color);font-size:var(--mw-font-size)}fieldset.form-field input::placeholder{color:var(--mw-idle-color);font-size:var(--mw-font-size)}fieldset.form-field label{position:absolute;top:calc(var(--mw-input-height)/2 - var(--label-size) - var(--mw-font-size)/2);margin-left:calc(var(--mw-inset) - var(--mw-border-width));font-size:var(--mw-font-size);cursor:text;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:transparent;z-index:1;pointer-events:none}fieldset.form-field .select-wrapper{outline:none !important}fieldset.form-field.animated legend::before{content:"";position:absolute;display:block;width:calc(100% - var(--mw-border-radius));right:calc(.5*var(--mw-border-radius));height:0;border-top:var(--mw-border-width) solid var(--mw-idle-color);-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;-webkit-transition:width calc(var(--mw-inputlabel-duration)*.8);transition:width calc(var(--mw-inputlabel-duration)*.8)}fieldset.form-field.animated legend{color:transparent}fieldset.form-field.animated input::-webkit-input-placeholder{opacity:1;-webkit-transition:opacity var(--mw-inputlabel-duration) step-end;transition:opacity var(--mw-inputlabel-duration) step-end}fieldset.form-field.animated input::-moz-placeholder{opacity:1;-moz-transition:opacity var(--mw-inputlabel-duration) step-end;transition:opacity var(--mw-inputlabel-duration) step-end}fieldset.form-field.animated input:-ms-input-placeholder{opacity:1;-ms-transition:opacity var(--mw-inputlabel-duration) step-end;transition:opacity var(--mw-inputlabel-duration) step-end}fieldset.form-field.animated input::-ms-input-placeholder{opacity:1;-ms-transition:opacity var(--mw-inputlabel-duration) step-end;transition:opacity var(--mw-inputlabel-duration) step-end}fieldset.form-field.animated input::placeholder{opacity:1;-webkit-transition:opacity var(--mw-inputlabel-duration) step-end;transition:opacity var(--mw-inputlabel-duration) step-end}fieldset.form-field.animated label{position:absolute;left:calc(var(--mw-input-padding-x) - var(--mw-border-width));font-size:var(--mw-font-size);-webkit-transition:font-size var(--mw-inputlabel-duration),opacity var(--mw-inputlabel-duration) step-end,-webkit-transform var(--mw-inputlabel-duration);transition:font-size var(--mw-inputlabel-duration),opacity var(--mw-inputlabel-duration) step-end,-webkit-transform var(--mw-inputlabel-duration);transition:font-size var(--mw-inputlabel-duration),transform var(--mw-inputlabel-duration),opacity var(--mw-inputlabel-duration) step-end;transition:font-size var(--mw-inputlabel-duration),transform var(--mw-inputlabel-duration),opacity var(--mw-inputlabel-duration) step-end,-webkit-transform var(--mw-inputlabel-duration)}fieldset.form-field.animated:has(input:not(:-moz-placeholder)) legend::before{width:0}fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)) legend::before{width:0}fieldset.form-field.animated:has(input:not(:placeholder-shown)) legend::before{width:0}fieldset.form-field.animated:has(input:not(:-moz-placeholder)) legend{color:var(--mw-idle-color)}fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)) legend{color:var(--mw-idle-color)}fieldset.form-field.animated:has(input:not(:placeholder-shown)) legend{color:var(--mw-idle-color)}fieldset.form-field.animated:has(input:not(:-moz-placeholder)) label{color:transparent}fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)) label{color:transparent}fieldset.form-field.animated:has(input:not(:placeholder-shown)) label{color:transparent}fieldset.form-field:hover{border-width:var(--mw-hover-border-width);border-color:var(--mw-hover-color);padding:0 calc(var(--mw-inset) - var(--mw-hover-border-width))}fieldset.form-field:hover legend::before{border-width:var(--mw-hover-border-width);border-color:var(--mw-hover-color)}fieldset.form-field:hover legend{color:var(--mw-hover-color)}fieldset.form-field.animated:hover legend{color:transparent}fieldset.form-field.animated:has(input:placeholder-shown):hover input::-webkit-input-placeholder{color:transparent}fieldset.form-field.animated:has(input:placeholder-shown):hover input::-moz-placeholder{color:transparent}fieldset.form-field.animated:has(input:placeholder-shown):hover input:-ms-input-placeholder{color:transparent}fieldset.form-field.animated:has(input:placeholder-shown):hover input::-ms-input-placeholder{color:transparent}fieldset.form-field.animated:has(input:-moz-placeholder):hover input::placeholder{color:transparent}fieldset.form-field.animated:has(input:-ms-input-placeholder):hover input::placeholder{color:transparent}fieldset.form-field.animated:has(input:placeholder-shown):hover input::placeholder{color:transparent}fieldset.form-field.animated:has(input:not(:-moz-placeholder)):hover legend{color:var(--mw-hover-color)}fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)):hover legend{color:var(--mw-hover-color)}fieldset.form-field.animated:has(input:not(:placeholder-shown)):hover legend{color:var(--mw-hover-color)}fieldset.form-field.animated:hover label{color:var(--mw-hover-color);left:calc(var(--mw-input-padding-x) - var(--mw-hover-border-width));top:calc(.5*var(--mw-input-height) - var(--label-size)*.5 - var(--mw-font-size) + var(--mw-hover-border-width))}fieldset.form-field:focus-within{border-width:var(--mw-focus-border-width);border-color:var(--mw-focus-color);padding:0 calc(var(--mw-inset) - var(--mw-focus-border-width))}fieldset.form-field:focus-within legend::before{border-width:var(--mw-focus-border-width);border-color:var(--mw-focus-color)}fieldset.form-field:focus-within legend{color:var(--mw-focus-color)}fieldset.form-field select:focus{color:var(--mw-focus-color)}fieldset.form-field.animated:focus-within legend::before{width:0}fieldset.form-field.animated:focus-within legend{color:var(--mw-focus-color)}fieldset.form-field.animated:has(input:not(:-moz-placeholder)):focus-within legend{color:var(--mw-focus-color)}fieldset.form-field.animated:has(input:not(:-ms-input-placeholder)):focus-within legend{color:var(--mw-focus-color)}fieldset.form-field.animated:has(input:not(:placeholder-shown)):focus-within legend{color:var(--mw-focus-color)}fieldset.form-field.animated:focus-within input::-webkit-input-placeholder{color:transparent}fieldset.form-field.animated:focus-within input::-moz-placeholder{color:transparent}fieldset.form-field.animated:focus-within input:-ms-input-placeholder{color:transparent}fieldset.form-field.animated:focus-within input::-ms-input-placeholder{color:transparent}fieldset.form-field.animated:focus-within input::placeholder{color:transparent}fieldset.form-field.animated:focus-within label{color:transparent;left:calc(var(--mw-input-padding-x) - var(--mw-hover-border-width))}fieldset.form-field[disabled],fieldset.form-field[disabled]:hover{background-color:transparent;border-color:var(--mw-disabled-color);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:not-allowed;padding:0 calc(var(--mw-inset) - var(--mw-border-width))}fieldset.form-field[disabled] input{cursor:not-allowed}fieldset.form-field[disabled] input::-webkit-input-placeholder{color:var(--mw-disabled-color);cursor:not-allowed}fieldset.form-field[disabled] input::-moz-placeholder{color:var(--mw-disabled-color);cursor:not-allowed}fieldset.form-field[disabled] input:-ms-input-placeholder{color:var(--mw-disabled-color);cursor:not-allowed}fieldset.form-field[disabled] input::-ms-input-placeholder{color:var(--mw-disabled-color);cursor:not-allowed}fieldset.form-field[disabled] legend,fieldset.form-field[disabled] input::placeholder{color:var(--mw-disabled-color);cursor:not-allowed}fieldset.form-field[disabled] input{height:calc(var(--mw-input-height) - var(--label-size) + 2*var(--mw-border-width));margin-top:calc(-1*var(--half-lbl))}fieldset.form-field[disabled]:hover{border-width:var(--mw-border-width)}fieldset.form-field[disabled]:hover input,fieldset.form-field[disabled]:hover select{padding-left:calc(var(--mw-padding-left) - var(--mw-border-width))}fieldset.form-field[disabled]:hover legend{margin-left:calc(var(--mw-padding-left) - var(--mw-label-padding) - var(--mw-border-width));border-color:transparent;border-color:var(--mw-disabled-color);color:var(--mw-disabled-color);cursor:not-allowed}fieldset.form-field[disabled] label{cursor:not-allowed}fieldset.form-field:has([required]) legend::after{content:" *"}fieldset.form-field:has([required]) label::after{content:" *"} \ No newline at end of file diff --git a/dist/css/materialize.min.css.map b/dist/css/materialize.min.css.map deleted file mode 100644 index 8b4f2110b7..0000000000 --- a/dist/css/materialize.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["file:///Users/wuda/Projects/materialize/node_modules/normalize.css/normalize.css","file:///Users/wuda/Projects/materialize/sass/tokens.module.css","file:///Users/wuda/Projects/materialize/sass/theme.module.css","file:///Users/wuda/Projects/materialize/sass/typography.module.css","file:///Users/wuda/Projects/materialize/sass/colors.module.css","file:///Users/wuda/Projects/materialize/sass/_typography.scss","file:///Users/wuda/Projects/materialize/sass/_variables.scss","file:///Users/wuda/Projects/materialize/sass/_global.scss","file:///Users/wuda/Projects/materialize/sass/_grid.scss","file:///Users/wuda/Projects/materialize/sass/transitions.css","file:///Users/wuda/Projects/materialize/sass/pulse.css","file:///Users/wuda/Projects/materialize/sass/_table_of_contents.scss","file:///Users/wuda/Projects/materialize/sass/_tapTarget.scss","file:///Users/wuda/Projects/materialize/components/button/_buttons.scss","file:///Users/wuda/Projects/materialize/sass/mixins.module.scss","file:///Users/wuda/Projects/materialize/components/collapsible/_collapsible.scss","file:///Users/wuda/Projects/materialize/components/badge/_badges.scss","file:///Users/wuda/Projects/materialize/components/card/_cards.scss","file:///Users/wuda/Projects/materialize/components/snackbar/_toast.scss","file:///Users/wuda/Projects/materialize/components/tabs/_tabs.scss","file:///Users/wuda/Projects/materialize/components/tooltip/_tooltip.scss","file:///Users/wuda/Projects/materialize/components/dropdown/_dropdown.scss","file:///Users/wuda/Projects/materialize/components/list/_collection.scss","file:///Users/wuda/Projects/materialize/components/list/_list.scss","file:///Users/wuda/Projects/materialize/components/dialog/_modal.scss","file:///Users/wuda/Projects/materialize/components/dialog/_materialbox.scss","file:///Users/wuda/Projects/materialize/components/chip/chips.css","file:///Users/wuda/Projects/materialize/components/appbar/appbar.css","file:///Users/wuda/Projects/materialize/components/navigation-drawer/_sidenav.scss","file:///Users/wuda/Projects/materialize/components/progress/_preloader.scss","file:///Users/wuda/Projects/materialize/components/carousel/_slider.scss","file:///Users/wuda/Projects/materialize/components/carousel/_carousel.scss","file:///Users/wuda/Projects/materialize/components/datepicker/_datepicker.scss","file:///Users/wuda/Projects/materialize/components/timepicker/_timepicker.scss","file:///Users/wuda/Projects/materialize/components/breadcrumb/_breadcrumb.scss","file:///Users/wuda/Projects/materialize/components/pagination/_pagination.scss","file:///Users/wuda/Projects/materialize/components/radio-button/_radio-buttons.scss","file:///Users/wuda/Projects/materialize/components/checkbox/_checkboxes.scss","file:///Users/wuda/Projects/materialize/components/switch/_switches.scss","file:///Users/wuda/Projects/materialize/components/slider/_range.scss","file:///Users/wuda/Projects/materialize/components/textfield/_input-fields.scss","file:///Users/wuda/Projects/materialize/components/textfield/_select.scss","file:///Users/wuda/Projects/materialize/components/textfield/_file-input.scss","file:///Users/wuda/Projects/materialize/components/textfield/formfields.css"],"names":[],"mappings":"CAAA,4EAUA,KACE,iBACA,8BAUF,KACE,SAOF,KACE,cAQF,GACE,cACA,eAWF,GACE,uBACA,SACA,iBAQF,IACE,gCACA,cAUF,EACE,6BAQF,YACE,mBACA,0BACA,iCAOF,SAEE,mBAQF,cAGE,gCACA,cAOF,MACE,cAQF,QAEE,cACA,cACA,kBACA,wBAGF,IACE,eAGF,IACE,WAUF,IACE,kBAWF,sCAKE,oBACA,eACA,iBACA,SAQF,aAEE,iBAQF,cAEE,oBAOF,gDAIE,0BAOF,wHAIE,kBACA,UAOF,4GAIE,8BAOF,SACE,2BAUF,OACE,sBACA,cACA,cACA,eACA,UACA,mBAOF,SACE,wBAOF,SACE,cAQF,6BAEE,sBACA,UAOF,kFAEE,YAQF,cACE,6BACA,oBAOF,yCACE,wBAQF,6BACE,0BACA,aAUF,QACE,cAOF,QACE,kBAUF,SACE,aAOF,SACE,aC3VF,MACE,qBAEA,mCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,qCAEA,qCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,sCACA,uCAEA,oCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,sCAEA,mCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,qCAEA,2CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,4CACA,6CAEA,iCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,mCAEA,sCACA,yCACA,gDACA,mDACA,wCACA,2CACA,kDACA,qDACA,uCACA,0CACA,iDACA,oDACA,oCACA,8CACA,uCACA,iDACA,yCACA,4CACA,sCACA,yCACA,8CACA,iDACA,sCACA,iDACA,8CACA,8CACA,qCACA,2CACA,8CACA,oCAEA,qCACA,wCACA,+CACA,kDACA,uCACA,0CACA,iDACA,oDACA,sCACA,yCACA,gDACA,mDACA,mCACA,6CACA,sCACA,gDACA,wCACA,2CACA,qCACA,wCACA,6CACA,gDACA,qCACA,gDACA,6CACA,6CACA,oCACA,0CACA,6CACA,mCAEA,0DACA,4DACA,oDACA,iDACA,mDACA,yDAEA,2DACA,6DACA,qDACA,kDACA,oDACA,sDAEA,0DACA,4DACA,oDACA,iDACA,mDACA,qDAEA,2DACA,6DACA,qDACA,kDACA,oDACA,sDAEA,4DACA,8DACA,sDACA,mDACA,qDACA,uDAEA,2DACA,6DACA,qDACA,kDACA,oDACA,sDAEA,uDACA,yDACA,iDACA,8CACA,gDACA,qDAEA,wDACA,0DACA,kDACA,+CACA,iDACA,sDAEA,uDACA,yDACA,iDACA,8CACA,gDACA,qDAEA,wDACA,yDACA,kDACA,+CACA,iDACA,sDAEA,yDACA,0DACA,mDACA,gDACA,kDACA,uDAEA,wDACA,yDACA,kDACA,+CACA,iDACA,sDAEA,wDACA,0DACA,kDACA,+CACA,iDACA,mDAEA,yDACA,0DACA,mDACA,gDACA,kDACA,uDAEA,wDACA,yDACA,kDACA,+CACA,iDACA,sDC7QF,YACE,mBACA,0DACA,gEACA,8EACA,oFACA,8DACA,oEACA,kFACA,wFACA,4DACA,kEACA,gFACA,sFACA,sDACA,4DACA,0EACA,gFACA,0DACA,gEACA,sEACA,0DACA,gEACA,0EACA,gFACA,0EACA,gFACA,0EACA,wDACA,oEACA,0EACA,sDAGF,mCACE,YACE,kBACA,yDACA,+DACA,6EACA,mFACA,6DACA,mEACA,iFACA,uFACA,2DACA,iEACA,+EACA,qFACA,qDACA,2DACA,yEACA,+EACA,yDACA,+DACA,qEACA,yDACA,+DACA,yEACA,+EACA,yEACA,+EACA,yEACA,uDACA,mEACA,yEACA,sDAMJ,mBACE,mBACA,0DACA,gEACA,8EACA,oFACA,8DACA,oEACA,kFACA,wFACA,4DACA,kEACA,gFACA,sFACA,sDACA,4DACA,0EACA,gFACA,0DACA,gEACA,sEACA,0DACA,gEACA,0EACA,gFACA,0EACA,gFACA,0EACA,wDACA,oEACA,0EACA,sDAGF,kBACE,kBACA,yDACA,+DACA,6EACA,mFACA,6DACA,mEACA,iFACA,uFACA,2DACA,iEACA,+EACA,qFACA,qDACA,2DACA,yEACA,+EACA,yDACA,+DACA,qEACA,yDACA,+DACA,yEACA,+EACA,yEACA,+EACA,yEACA,uDACA,mEACA,yEACA,qDC1IF,eACE,mEACA,mEACA,8DACA,0DACA,8DACA,yDACA,oEACA,sEAEF,gBACE,oEACA,oEACA,+DACA,2DACA,+DACA,0DACA,qEACA,uEAEF,eACE,mEACA,mEACA,8DACA,0DACA,8DACA,yDACA,oEACA,sEAEF,gBACE,oEACA,oEACA,+DACA,2DACA,+DACA,0DACA,qEACA,uEAEF,iBACE,qEACA,qEACA,gEACA,4DACA,gEACA,2DACA,sEACA,wEAEF,gBACE,oEACA,oEACA,+DACA,2DACA,+DACA,0DACA,qEACA,uEAEF,YACE,gEACA,gEACA,2DACA,uDACA,2DACA,sDACA,iEACA,mEAEF,aACE,iEACA,iEACA,4DACA,wDACA,4DACA,uDACA,kEACA,oEAEF,YACE,gEACA,gEACA,2DACA,uDACA,2DACA,sDACA,iEACA,mEAEF,aACE,iEACA,iEACA,4DACA,wDACA,4DACA,uDACA,kEACA,oEAEF,cACE,kEACA,kEACA,6DACA,yDACA,6DACA,wDACA,mEACA,qEAEF,aACE,iEACA,iEACA,4DACA,wDACA,4DACA,uDACA,kEACA,oEAEF,aACE,iEACA,iEACA,4DACA,wDACA,4DACA,uDACA,kEACA,oEAEF,cACE,kEACA,kEACA,6DACA,yDACA,6DACA,wDACA,mEACA,qEAEF,aACE,iEACA,iEACA,4DACA,wDACA,4DACA,uDACA,kEACA,oECpJF,sDACA,gDACA,4DACA,sDACA,0EACA,oEACA,gFACA,0EAEA,0DACA,oDACA,gEACA,0DACA,8EACA,wEACA,oFACA,8EAEA,wDACA,kDACA,8DACA,wDACA,4EACA,sEACA,kFACA,4EAEA,kDACA,4CACA,wDACA,kDACA,sEACA,gEACA,4EACA,sEAEA,4DACA,sDACA,kEACA,4DAEA,sDACA,gDACA,4DACA,sDAEA,sEACA,gEACA,4EACA,sEAEA,sDACA,gDAEA,4EACA,sEAEA,sEACA,gEAEA,sEACA,gEAEA,oDACA,8CAEA,gEACA,0DAEA,sEACA,gEAEA,kDACA,4CCtEA,EACE,qBAGF,KAEE,YCiCW,4GDhCX,mBACA,MCgCW,kCD/BX,sCALF,KAMI,gBAEF,0CARF,KASI,kBAEF,2CAXF,KAYI,gBAIJ,kBACC,gBACA,gBAID,kDACA,aCgBc,ODhBgB,2CAC9B,aCgBc,QDhBgB,qDAC9B,aCgBc,QDhBgB,qDAC9B,aCgBc,QDhBgB,4CAC9B,aCgBc,QDhBgB,oDAC9B,aCgBc,QDhBgB,kDAG9B,qBACA,uBACA,oBACA,uBACA,sBAKI,0CAHJ,WAIM,kBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,mBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,mBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,mBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,oBADF,0CAHJ,WAIM,mBAMJ,0CAVF,WAWI,kBErDJ,KACE,sBAGF,mBACE,mBAGF,KACE,gDACA,wCAGF,sCAKE,YDsBW,4GCnBb,EACE,MDjBW,oCCkBX,qBACA,0CAIF,gDAEA,qBAGA,qmBACE,2BAIF,ydACE,iGAKF,wDACE,iGAIF,gHACE,kGAMF,kBACE,uGAMF,WACE,yGAMF,kBACE,0GAKF,WACE,2BACA,iBACE,oEAKJ,SACE,WACA,gBACA,qDAIF,+FAGA,EACE,oBACA,OACE,WACA,iBAGF,QACE,YAGF,OACE,eAEF,QACE,eAEF,SACE,eAEF,QACE,eAKJ,cACE,eACA,kBACA,WAIF,0CAEE,eACA,YAIF,oBACE,kBACA,gBACA,aAEA,8BACE,kBACA,MACA,OACA,QACA,SACA,WAEA,kCACE,UACA,kBACA,SACA,SACA,eACA,gBACA,+BACA,2BAMN,qBACE,kBAGF,QACE,0BAIF,aACE,kDAGF,MACE,gBACA,6CAQF,+BACA,0CAME,8CADF,4CAC8B,yBAI5B,8CADF,sBAC+B,yBAI7B,2CADF,oBAC6B,yBAI3B,mEADF,kBAEI,yBAKF,2CADF,oBAC4B,yBAI1B,4CADF,0BACkC,yBAIhC,4CADF,qBACkC,0BAIhC,2CADF,eAC4B,0BAI1B,mEADF,gBAEI,0BAKF,8CADF,eAC8B,0BAI5B,2CADF,uBAC6B,0BAI3B,8CADF,yBAC+B,0BAM7B,8CADF,sBAC8B,mBAI9B,aACE,gBACA,iBACA,0DACA,eACE,wCAEF,eACE,kCAEF,gEAEE,gBACA,gBACA,aACA,mBACA,8BACA,iBAIJ,gBACE,eACA,qBAIF,YACE,YAGF,MACE,WACA,cACA,yBACA,iBAGE,iBACE,mBAEF,sCACE,iCAIJ,yBACE,sCAEA,+BACE,iCAIJ,YACE,6CAIA,sDACE,kBAKN,GACE,4DAGF,MACE,iBACA,mBACA,gBACA,sBACA,gBAIF,8CAEE,uBACE,WACA,yBACA,iBACA,cACA,kBAEA,uCACE,YAEF,oDAEE,SACA,mBAEF,0BACE,gBAEF,6BACE,cACA,WAEA,gCACE,cACA,mBAEA,2CACE,YAIN,6BACE,cACA,WACA,kBACA,gBACA,mBAEA,gCACE,qBACA,mBAGJ,0BACE,cACA,iBAEF,0BACE,cACA,kBACA,gBAEF,0BACE,mBACA,eAGF,6BACE,SACA,4DAMN,iBACE,kBACA,sBACA,SACA,gBAEA,uEACE,kBACA,MACA,OACA,WACA,YAQJ,8BAGA,4BACA,8BACA,wCAGA,4BACA,8BAGA,uEACA,0BACA,+DACA,kFACA,iCAeI,KACE,oBAIA,MACE,wBADF,MACE,0BADF,MACE,2BADF,MACE,yBAKD,MACE,yBACA,0BAKH,MACE,wBACA,2BApBJ,KACE,yBAIA,MACE,6BADF,MACE,+BADF,MACE,gCADF,MACE,8BAKD,MACE,8BACA,+BAKH,MACE,6BACA,gCApBJ,KACE,wBAIA,MACE,4BADF,MACE,8BADF,MACE,+BADF,MACE,6BAKD,MACE,6BACA,8BAKH,MACE,4BACA,+BApBJ,KACE,yBAIA,MACE,6BADF,MACE,+BADF,MACE,gCADF,MACE,8BAKD,MACE,8BACA,+BAKH,MACE,6BACA,gCApBJ,KACE,uBAIA,MACE,2BADF,MACE,6BADF,MACE,8BADF,MACE,4BAKD,MACE,4BACA,6BAKH,MACE,2BACA,8BApBJ,KACE,yBAIA,MACE,6BADF,MACE,+BADF,MACE,gCADF,MACE,8BAKD,MACE,8BACA,+BAKH,MACE,6BACA,gCApBJ,KACE,uBAIA,MACE,2BADF,MACE,6BADF,MACE,8BADF,MACE,4BAKD,MACE,4BACA,6BAKH,MACE,2BACA,8BApBJ,QACE,uBAIA,SACE,2BADF,SACE,6BADF,SACE,8BADF,SACE,4BAKD,SACE,4BACA,6BAKH,SACE,2BACA,8BApBJ,KACE,qBAIA,MACE,yBADF,MACE,2BADF,MACE,4BADF,MACE,0BAKD,MACE,0BACA,2BAKH,MACE,yBACA,4BApBJ,KACE,0BAIA,MACE,8BADF,MACE,gCADF,MACE,iCADF,MACE,+BAKD,MACE,+BACA,gCAKH,MACE,8BACA,iCApBJ,KACE,yBAIA,MACE,6BADF,MACE,+BADF,MACE,gCADF,MACE,8BAKD,MACE,8BACA,+BAKH,MACE,6BACA,gCApBJ,KACE,0BAIA,MACE,8BADF,MACE,gCADF,MACE,iCADF,MACE,+BAKD,MACE,+BACA,gCAKH,MACE,8BACA,iCApBJ,KACE,wBAIA,MACE,4BADF,MACE,8BADF,MACE,+BADF,MACE,6BAKD,MACE,6BACA,8BAKH,MACE,4BACA,+BApBJ,KACE,0BAIA,MACE,8BADF,MACE,gCADF,MACE,iCADF,MACE,+BAKD,MACE,+BACA,gCAKH,MACE,8BACA,iCApBJ,KACE,wBAIA,MACE,4BADF,MACE,8BADF,MACE,+BADF,MACE,6BAKD,MACE,6BACA,8BAKH,MACE,4BACA,+BApBJ,QACE,wBAIA,SACE,4BADF,SACE,8BADF,SACE,+BADF,SACE,6BAKD,SACE,6BACA,8BAKH,SACE,4BACA,+BAOR,gBACE,kBACA,UACA,aACA,kBAGF,mBACE,iBAIF,6FAEE,kCACA,6BCreF,WACE,cACA,iBACA,UAGF,2CACE,WACE,WAIJ,2CACE,WACE,WAIJ,SACE,eAsBF,KACE,mBAGF,KACE,aACA,sCACA,oBAGA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,mCACA,mCACA,mCAEA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,qCACA,sCACA,sCAGA,2CACE,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,mCACA,mCACA,mCAEA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,qCACA,sCACA,uCAIF,2CACE,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,iCACA,mCACA,mCACA,mCAEA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,oCACA,qCACA,sCACA,uCAIF,4CACE,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,kCACA,oCACA,oCACA,oCAEA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,qCACA,sCACA,uCACA,wCAMJ,WACA,mCACA,kCACA,iCACA,mCACA,iCC3KA,kBACE,yEAEF,4BACE,mBACA,oCAEF,2BACE,mBCRF,OACE,iBACA,kBAEA,UACE,WACA,cACA,kBACA,oBACA,WACA,YACA,MACA,OACA,yBACA,sBACA,qCACA,qEACA,YAIJ,2BACE,GACE,UACA,mBAEF,IACE,UACA,qBAEF,KACE,UACA,sBChCJ,mBACE,gBACA,yBACE,eAEF,sBACE,UAEF,qBACE,qBACA,gBACA,oCACA,kBACA,YACA,iBACA,0DACA,2BACE,wCACA,kBAEF,4BACE,kCACA,gBACA,kBACA,kDCxBN,oBACE,YACA,aACA,eACA,aACA,kBACA,6BAGF,yBACE,mBACA,yBAEA,qCACE,mBACA,YACA,WACE,wFAIJ,kDACE,mBAEF,iDACE,mBACA,qEACA,WACE,2CAMN,YACE,kBACA,eACA,kBACA,uDACA,kCACA,wGACA,WACA,YACA,UACA,mBACA,mGAIF,oBACE,kBACA,mBAGF,iBACE,kBACA,kBACA,cAEA,iDAEE,WACA,cACA,kBACA,WACA,YACA,kBACA,6CAEF,yBACE,mBACA,yBAEF,wBACE,kBACA,WACE,wCAGF,WAIJ,mBACE,QACA,SACA,cACA,6BACA,gCAEA,gEAEE,gBAIJ,0CACE,gCACE,YACA,cC/FF,MACE,mBACA,2BACA,oBACA,yBACA,oBACA,yBACA,sBAIJ,mDCLE,ODOE,kBCNF,cDOE,yBCNF,aDOE,mBCNF,cDOE,mBCNF,UDOE,qBCNF,gBACA,qBACA,oBACA,mBACA,YACA,eACA,0CACA,mBACA,UACA,iBACA,yCAEA,iFACE,uDDFJ,sKACE,kBAGF,iFACE,6FAGF,qFACE,8FAGF,sLACE,kBACA,oCAGF,yFACE,6BAGF,6FACE,8BAKF,qECpBE,qCACA,6CAEA,0LAEE,qCAGF,6FAEE,qGAGF,6FAEE,qGAkHF,6HACE,gDACA,mBD3GJ,iECFE,iDACA,yDAEA,kLAEE,iDAGF,yFAEE,6HAGF,yFAEE,6HA4FF,yHACE,gDACA,mBAFF,qIACE,gDACA,mBDnGJ,6ECmCE,+BACA,kCACA,6CAEA,0MAEE,kCAGF,qGACE,kFAGF,qGACE,kFACA,6CAGF,iHACE,uBACA,iFA0CF,qIACE,gDACA,mBD/FJ,uEC2DE,kCACA,+BAEA,0MAEE,kCAGF,qGACE,kFAGF,qGACE,kFAGF,oHACE,uBAiBF,6IACE,gDACA,mBDzFJ,qSC8EE,0EACA,qFACA,oBACA,gBACA,eDvEF,cAOE,MP/EqB,KOgFrB,OPhFqB,KOiFrB,+CACA,uDACA,cPlFuB,KOmFvB,UACA,aACA,sBACA,mBACA,kBACA,gBACA,UAEA,gCACA,eACA,sBACA,kBAEA,oBAEE,yHAGF,oBACE,iBPzG+B,kCO6GjC,qBACE,gBAGF,wBACE,WACA,YACA,UACA,oCACE,aAQJ,wBACE,mDACA,8BACA,+BAEA,oCACE,0CAOJ,0BACE,kBACA,WACA,aAEA,+BACE,WACA,UAIJ,gBACE,mBACA,iBACA,cACA,qBACA,kBAKJ,oBACE,YAIF,kBACE,eACA,WACA,YACA,iBACA,gBACA,YAGE,4BACE,mBACA,eACA,qBAKJ,mEAEE,mBAEA,yEACE,iBACA,WACA,QACA,2BACA,YACA,UAEA,YAEA,+EACE,qBACA,sBAKN,kCACE,mBAEA,qCACE,gBACA,cACA,UACA,WAEA,wCACE,sBAKN,mCACE,mBAEA,sCACE,SACA,YACA,aACA,8BAEA,yCACE,kBAKN,0BACE,UACA,YAGE,qCACE,UAIJ,6BACE,aACA,MACA,SACA,UAEA,gCACE,OACA,qBACA,SACA,YACA,gBAEA,kCACE,cACA,gBACA,kBACA,WACA,YACA,+BACA,gBACA,MPvQc,iCOwQd,iBACA,UAEA,oCACE,oBAOV,qBACE,OACA,QACA,kBACA,kBACA,YACA,SACA,kBAEA,wBACE,mBAGF,oCACE,UAIJ,gCACE,kBACA,MACA,OACA,WACA,MPzSmB,KO0SnB,OP1SmB,KO2SnB,iBP/SyB,8BOgTzB,cP3SqB,KO4SrB,mBAOJ,WAEE,mCACA,eACA,eAEA,aACE,iBAKJ,WAEE,mCACA,eAEA,aACE,iBAKJ,WACE,cAGF,yEACE,sBE3VF,aACE,eACA,qBACA,yDACA,2DACA,0DACA,sBAIF,oBACE,aACA,eACA,0CACA,gBACA,aACA,4DAEA,0BACE,UAGF,sBACE,WACA,iBACA,qBACA,kBACA,kBAIJ,2BACE,YACA,kBACA,6GACA,eACA,eACA,mCAGF,mCACE,YAGF,4CACE,iCAGF,4BACE,YAGF,kBACE,aACA,4DACA,sBACA,eACA,gBAKF,oBACE,YACA,gBAEA,uBACE,oEAEA,cACA,4DAGF,8BACE,qEACA,cC7EJ,MACE,qBAGF,WACE,eACA,cACA,iBACA,kBACA,eACA,gCACA,2BACA,6CACA,YACA,sBAEA,eACE,gBACA,gBACA,qCACA,6CACA,kBAEF,qBACE,eAGF,sCACE,qCAIJ,mBACE,qCAKF,wBACE,qBACA,WACA,gBACA,gCACA,2BACA,4BAIF,4BACE,iDAGF,wBACE,iBAEA,gCACE,iBACA,SAIJ,0CACE,6CAGF,oBACE,sDAGF,iBACE,qBACA,WACA,iBCtEF,YACE,2BACA,aACA,sBACA,mBAEA,6CAGF,MACE,0GAEA,kBAEA,yCACA,2BACA,mBAGA,kBACE,eACA,gBAIF,qCACE,kBAEA,yEACE,eACA,gBAGF,mHACE,eAGF,+EACE,gBACA,gBAGF,4EACE,kBACA,SACA,OACA,QAIJ,YACE,aAGF,aACE,aAGF,YACE,aAIF,iBACE,aAGE,0GACE,YACA,gBACA,iBAEA,sHACE,YAKN,6BACE,cAEA,iCACE,0BACA,eACA,WAIJ,+BACE,aACA,sBACA,OACA,kBAEA,6CACE,YAOJ,iCACE,UAGF,iCACE,UACA,oBAIJ,kBACE,kBAGA,sBACE,cACA,0BACA,kBACA,OACA,QACA,MACA,SACA,WAGF,8BACE,kCACA,kBACA,SACA,OACA,eACA,aAGF,6BACE,kBACA,OACA,QACA,MACA,SACA,eAGF,gCACE,kBAIJ,oBACE,aACA,0BAEA,sBACE,SAGF,gCACE,cACA,iBACA,kBAEA,kCACE,iBAGF,0CACE,eAKN,mBACE,iBAEA,8BACE,0BAGF,qBH7KF,OG+KM,kBH9KN,cG+KM,yBH9KN,aG+KM,mBH9KN,cG+KM,mBH9KN,UG+KM,qBH9KN,gBACA,qBACA,oBACA,mBACA,YACA,eACA,0CACA,mBACA,UACA,iBACA,yCAEA,2BACE,uDGoKE,iCACE,oBAGF,gCACE,qBAKF,+HAIE,yBAKN,mBACE,aACA,kBACA,6CACA,WACA,gBACA,OACA,SACA,YACA,UACA,aAEA,+BACE,eACA,cC9NN,iBACE,cACA,eACA,cAEA,8CALF,iBAMI,eACA,WAEF,qEATF,iBAUI,QACA,UACA,eAEF,2CAdF,iBAeI,QACA,SACA,eAIJ,OAEE,kBACA,SACA,WACA,gBACA,kBACA,eACA,YACA,gBAIA,kBACA,mBAEA,eACA,gBACA,iBAEA,6CACA,qDAEA,aACA,mBACA,8BACA,eAEA,qBACE,0CACA,gBACA,mBACA,iBAGF,eACE,mBAGF,8CAvCF,OAwCI,WACA,iBC/DJ,MACE,eACA,qBACA,kBACA,gBACA,kBACA,WACA,6CACA,cACA,mBACA,qBAEA,uBACE,+BAEA,8BACE,0CAGF,iIAGE,0BAGF,oCACE,iCAGF,yEAEE,+BAGF,6GAGE,qCAGF,kCACE,gDAIJ,uBACE,aAEA,4BACE,YAIJ,WACE,eACA,qBACA,qBACA,kBACA,iBACA,UACA,SAEA,4BACE,kBACA,QACA,sBAGF,gBACE,YACA,iBAGF,aACE,6CACA,aACA,sBACA,WACA,YACA,gBACA,eACA,eACA,uBACA,iBACA,gBACA,WACE,2CAGF,oBACE,+BAGF,0DAGE,kCAGF,mBACE,iFAGF,mBACE,uDAGF,oBACE,kFAGF,uCAEE,aAIJ,kDAEE,qCACA,eACA,+BAEA,0EACE,+BAKN,iBACE,kBACA,SACA,WACA,6CACA,uBACA,0BAGF,2BACE,YAEA,6BACE,cAGF,4CACE,cACA,kBACA,SACA,sBAON,8CACE,MACE,aAEA,WACE,YAEA,aACE,gBCtKR,kBACE,cACA,kBACA,6CACA,qDACA,gEACA,uDACA,2DACA,2DACA,gBACA,UACA,gBACA,mBACA,eACA,iBACA,gBACA,oBACA,kBACA,gBACA,gBACA,OACA,MACA,oBACA,aACA,mBACA,kBACA,aAGF,UACE,kBACA,UACA,WACA,WACA,0BACA,qDACA,WACA,uBACA,kBCnCF,UACE,aACA,UACA,YAGF,kBACE,eACA,qBAEA,6CACA,SACA,aACA,gBACA,gBACA,UACA,kBACA,OACA,MACA,aACA,qBACA,iBACA,mBAEA,qBACE,WACA,wCACA,eACA,WfbmB,KecnB,mBACA,WACA,gBAEA,6BACE,aACA,WAEF,iDACE,eACA,kCACA,cACA,iBACA,kBAEF,gCACE,QACA,OACA,YAGF,yBACE,eACA,oBACA,WACA,kBACA,WAGJ,sEACE,oGAKF,iDACE,iCAKJ,yDACE,QACA,OACA,YACA,eAGF,kBACE,eC/EF,YACE,eACA,qBACA,sBACA,qDACA,kBACA,gBACA,kBAEA,6BACE,+BACA,mBACA,kBACA,SACA,4DAGA,oCACE,gBACA,kBACA,kBAGA,mIAEE,kBACA,WACA,YACA,gBACA,UACA,qBACA,sBAGF,6CACE,eACA,iBACA,WACA,kDACA,kBAIF,2CACE,eAGF,sCACE,SAGF,uDACE,kBACA,SACA,WAIJ,wCACE,mBAGF,oCACE,6CACA,qCAEA,uDACE,qCAKN,8BACE,cACA,gBACA,kCAGE,iDACE,iCAMJ,2CACE,+BACA,4DACA,kBAGF,yCACE,kBAGF,gDACE,kBAON,mBACE,YACA,kCAGF,yBACE,SACA,YC7GF,WACE,oBCCA,mCACA,4BACA,sBACA,6BACA,gHAGA,YACA,aACA,UACA,eACA,UACA,yCACA,wBACA,+CAGA,aACE,aACA,sBAGF,8CAvBF,OAwBI,WAIF,iBACE,0BAGF,qBACE,6BACA,2CACA,cACA,gBACA,MAIF,sBACE,+BAEF,qBACE,aACA,wEACA,6BACA,iBACA,cACA,gBACA,SAGA,8BAGF,oBACE,eAIF,4DACE,SAKJ,oBACE,gBACA,eACA,4BACA,6BACA,2BC7EF,eACE,cACA,eACA,kBACA,uBACA,mCAGE,kCACE,WAGJ,sBACE,gBAIJ,qBACE,eACA,MACA,QACA,SACA,OACA,gDACA,aACA,oBAGF,qBACE,eACA,aACA,wCACA,iBACA,SACA,OACA,WACA,kBACA,eACA,YACA,aACA,mCCxCF,MACE,kBACA,uBACA,eAEA,6CACA,qCACA,oBACA,mBACA,QACA,SACA,YACA,4BACA,6BACA,2BACA,gBACA,kBACA,mBACA,iBACA,mBAEF,YACE,aACA,6CACA,qCAGF,eACE,6BACA,yCACA,iBACA,mBAGF,UACE,SACA,WACA,YACA,iBACA,mBAGF,sBACE,gCACA,6CAGF,aACE,YACA,kBACA,YACA,WACA,UACA,aACA,uBACA,qBACA,eAGF,mBACE,+CAGF,OACE,aACA,QACA,eACA,YACA,gBACA,iBACA,YAEA,aACA,mBAEF,aACE,oDACA,iDAEF,mBACE,+DAEF,oDACE,gBACA,SACA,wCACA,qBACA,eAGA,YACA,UACA,SACA,UACA,YACA,kBACA,gBACA,gBAGF,0DACE,SACA,gBAEF,yBACE,YAEF,6BACE,aACA,gBAGF,eACE,iBACA,UACA,wBAEF,eACE,kBACA,UACA,wBAEF,mBACE,gBACA,4BC5HF,MACE,sBACA,6BACA,+BAGF,aACE,YACA,6CACA,iBACA,kBACA,aACA,mBAGF,QACE,qCACA,mCAGF,kCACE,qBACA,SACA,aACA,mBACA,QAGF,qCACE,gCACA,UAGF,uCACE,gCACA,qCACA,cACA,eAGF,oBACE,qCACA,wCACA,qBACA,UAGF,mBACE,qBACA,eACA,eAGF,cACE,eACA,YCpDF,SACE,uBACA,0BACA,wBACA,4BACA,kDAEA,eACA,2BACA,OACA,MACA,SACA,4BACA,aACA,UACA,YACA,gBACA,sBACA,2BACA,4BACA,iBAEA,iDACA,6CAIA,uBACE,QACA,2BACA,UACA,2BAGF,sBACE,SASF,iBACE,iCAGF,0IAGE,oFAGF,gDAEA,YACE,gBACA,aACA,qBAEF,cAIE,cACA,iCASA,aACA,kCACA,mCACA,gBACA,mBACA,gBACA,oBAEA,0EACE,iDACA,gFAGE,oFAIJ,4FACE,iBAIF,qJAEE,oBACA,sBACA,kBAIJ,kBACE,6CAGF,oBACE,eACA,oBACA,UACA,mCACA,gBACA,uCAIF,oBACE,kBACA,wEACA,8CAEA,sBACE,YACA,UAEA,4BACE,+BAIJ,gCACE,gBACA,kBACA,MACA,QACA,SACA,OACA,WAGF,iFACE,cAGF,4BACE,YACA,WAGF,qDAEE,mCACA,gDAGF,0BACE,gBACA,gBAGF,2BACE,oBACA,gBAMN,aACE,YACA,eACA,MACA,OACA,YAEA,2BACE,QAKJ,uBACE,OACA,wBACA,eAEA,qCACE,QACA,UAKJ,8CAEI,uBACE,4BAEA,qCACE,2BAGJ,WACE,iCAEF,oBACE,yDAKN,2BACE,UAGF,iBACE,eACA,MACA,OACA,QACA,UACA,aACA,gCACA,YACA,aAMA,0DACE,YACA,gBAEF,wEACE,YAEF,oEACE,YClPJ,UACE,kBACA,WACA,cACA,WACA,qDACA,kBACA,sBACA,gBACA,yDAEA,uBACE,kBACA,MACA,OACA,SACA,6CACA,4BAGF,yBACE,6CAEA,gCACE,WACA,kBACA,yBACA,MACA,OACA,SACA,uBAEA,8EAIF,+BACE,WACA,kBACA,yBACA,MACA,OACA,SACA,uBAEA,+EACA,sBAKN,yBACE,GACE,UACA,WAEF,IACE,UACA,WAEF,KACE,UACA,YAIJ,+BACE,GACE,WACA,WAEF,IACE,UACA,UAEF,KACE,UACA,WAgCJ,mBACE,qBACA,kBACA,WACA,YAEA,yBACE,WACA,YAGF,uBACE,WACA,YAGF,0BAEE,0DACA,kDAIJ,oCACE,qCAGF,4BACE,6BAGF,eACE,kBACA,WACA,YACA,UACA,yCAGF,iCAEE,qBAGF,+BAEE,qBAGF,qCAEE,qBAGF,mCAEE,qBAgBF,oCAEE,0JACA,kJAGF,mCAEE,yJACA,iJAGF,sCAEE,4JACA,oJAGF,qCAEE,2JACA,mJAGF,6LAME,UACA,uFACA,+EAGF,sCACE,uCACA,qCACA,uCACA,qCACA,uCACA,qCACA,uCACA,sCAGF,8BACE,+BACA,6BACA,+BACA,6BACA,+BACA,6BACA,+BACA,8BAGF,oCACE,eACA,cACA,cACA,cACA,cACA,gBAGF,4BACE,eACA,cACA,cACA,cACA,cACA,gBAGF,mCACE,eACA,cACA,cACA,cACA,eAGF,2BACE,eACA,cACA,cACA,cACA,eAGF,sCACE,eACA,cACA,cACA,cACA,eAGF,8BACE,eACA,cACA,cACA,cACA,eAGF,qCACE,eACA,cACA,cACA,cACA,gBAGF,6BACE,eACA,cACA,cACA,cACA,gBAOF,WACE,kBACA,MACA,SACA,UACA,YACA,gBACA,qBAGF,mBACE,YACA,WAGF,gBACE,qBACA,kBACA,UACA,YACA,gBACA,qBAEA,wBACE,WACA,YACA,iBACA,mBACA,qBACA,6CACA,kBACA,uBACA,eACA,kBACA,MACA,QACA,SAGF,6BACE,OACA,4CACA,iCACA,yBAEF,8BACE,WACA,2CACA,kCACA,0BAMJ,qCAEE,8EACA,sEAGF,sCAEE,+EACA,uEAGF,6BACE,sCACA,oCACA,qCAGF,qBACE,8BACA,4BACA,6BAGF,8BACE,uCACA,mCACA,sCAGF,sBACE,+BACA,2BACA,8BAGF,2BAEE,sGACA,8FAGF,4BACE,eACA,cAGF,oBACE,eACA,cC9ZF,QACE,kBACA,aACA,WAGA,mBACE,YACA,WACA,kBACA,MACA,OACA,QACA,SAEA,6BACE,eACA,qBACA,YAGF,iCACE,eACA,qBACA,UACA,YAEA,iDACE,qCAEA,wDACE,kDAOR,gBACE,6CACA,SACA,aACA,eACA,qBAEA,mBACE,eACA,qBACA,UACA,kBACA,MACA,OACA,UACA,WACA,eACA,gBAEA,uBACE,YACA,WACA,sBACA,2BAGF,4BACE,WACA,kBACA,QACA,SACA,UACA,UAEA,8BACE,0BAIJ,0BACE,UAKN,oBACE,eACA,qBACA,kBACA,kBACA,OACA,QACA,SACA,SAEA,oCACE,qBACA,kBACA,YACA,WACA,cAGF,wCACE,kBACA,MACA,OACA,WACA,YACA,eACA,kDACA,gCACA,kBACA,eAEA,+CACE,6CClHR,UACE,yBAEA,gBACA,kBACA,WACA,8BACA,kBACA,4BACA,wBAEA,0BACE,MACA,OAEA,+CACE,kBACA,OACA,QACA,YACA,UAEA,+DACE,YAIJ,yCACE,WACA,YACA,kCACA,kBACA,MACA,OAEA,4CACE,eACA,gBACA,iBAGF,2CACE,eAKN,yBACE,kBACA,sCACA,uCACA,kBACA,MACA,OAEA,6BACE,WAIJ,sBACE,eACA,qBACA,kBACA,kBACA,OACA,QACA,SACA,SAEA,sCACE,qBACA,kBACA,eACA,WACA,UACA,gBACA,qCACA,gCACA,kBAEA,6CACE,kDAMN,uGAEE,oBCxFJ,sBACE,aACA,sBACA,gBACA,UACA,wDAGF,qBACE,aACA,8BACA,YACA,cAEA,wCACE,aAIA,2CACE,YACA,iBACA,mBACA,kBACA,kBAEA,iDACE,kCACA,kFAGF,sDACE,+BAIJ,4CACE,aAIJ,sCACE,UACA,sBAGF,iFAEE,+BAGF,wCACE,WAGF,yCACE,WAGF,kEAEE,oBACA,mBlBtDF,OkBwDwB,KlBvDxB,cANgB,yBAOhB,aANe,mBAOf,cANgB,mBAOhB,UANY,qBAOZ,gBACA,qBACA,oBACA,mBACA,YACA,eACA,0CACA,mBACA,UACA,iBACA,yCAEA,8EACE,uDkBwCA,8EACE,kFAIJ,0EAEE,4CAIJ,wBACE,YACA,eACA,eACA,+BACA,YAKF,yBACE,YAIA,kBACA,kEACA,gBAEA,oCACE,cACA,iBACA,iBACA,qCAGF,oCACE,cACA,iBACA,iBACA,gBAIA,+CACE,iBAON,+BACE,cAGF,kBACE,YACA,eACA,cAEA,wBACE,mBAGF,qBACE,iBACA,kBAGF,qBACE,YAGF,uBACE,qBACA,6CAGF,kCACE,UACA,wCAGA,2CACE,kCAmBN,iGAGE,kBAEA,sHACE,kBACA,QACA,WACA,YACA,WACA,uDACA,UAIJ,kFAEE,UAGF,0CACE,SAGF,2DACE,uDAGF,uBACE,+BACA,YACA,iBACA,cACA,WACA,kBACA,WACA,cACA,eACA,cACA,kBACA,UAEA,6BACE,iFAGF,6BACE,yCAGF,oCACE,6CACA,qCAEA,0CACE,qDACA,kCAIJ,iGAEE,qCACA,oBAKJ,mBACE,YACA,cACA,mBACA,aACA,8BAGF,wEAIE,kCACA,eAGF,kBACE,gCAIF,kBACE,+CACA,gBACA,wDCxQF,sBACE,aACA,sBACA,gBACA,UACA,wDAGF,cACE,qCAIF,4BACE,WACA,YAEA,kCACA,gBAGF,2BACE,aACA,eACA,gBACA,0CACA,gBAEA,iBACA,8BAEA,4CACE,YACA,oCACA,kBACA,eACA,cAIJ,2BACE,oBAGF,kCACE,YACA,oBAGF,kEAEE,cACA,eAGF,6EAGE,eAGF,kFAEE,YACA,sBACA,SACA,kBACA,wCACA,qDAEA,8FACE,uDAIJ,kCACE,aACA,kBAOF,0BACE,iBAIA,gBAGF,uBACE,eACA,iBAGF,4DAEE,aACA,WACA,0CACA,2CACA,iBACA,sBACA,kBAEA,6CAGF,8BACE,6BACA,4BAGF,8BACE,aACA,yBACA,0BAIF,2BACE,cACA,eAIF,kBACE,qDACA,kBACA,YACA,aACA,iBACA,kBACA,8BACA,iBAGF,oCAEE,kBACA,OACA,QACA,MACA,SAGF,oBACE,kBAGF,iBACE,kBACA,wCACA,iBACA,kBACA,WACA,YACA,kBACA,eACA,eAGF,+CAEE,iFAGF,iBACE,yCAGF,qBACE,UAEA,sCACE,0BAGF,wCACE,0BAIJ,mBACE,yBAEA,wBACE,mCACA,eACA,qBAIJ,uBACE,YAGF,2BACE,YACA,iCAGF,sBACE,YACA,iCAKF,mBACE,cACA,iBACA,aACA,8BAGF,kBACE,gCAGF,kBACE,kCAGF,oCAEE,eAIF,kBACE,gBACA,gBACA,wDACA,kBAGA,wCACE,0CACA,2CAIA,2EACE,cAGF,0EACE,gBAIJ,6CACE,iBAGF,oCACE,gBAKJ,2CACE,sBACE,WACA,gBAGF,sBACE,mBAGF,4BACE,eAGF,2BAEE,sBACA,kBACA,kBAGF,2BACE,aAGF,0BACE,kBAGF,uBACE,aACA,YACA,gBAQF,4DAEE,YAEA,2CACA,4CACA,uCACA,6CAGF,8BACE,0BACA,6BAGF,8BACE,cACA,4BACA,yBAGF,kBACE,kBAIF,kBACE,UACA,gBAGE,qJAEE,cAGF,0EACE,kBAGF,iEACE,eACA,gBAIJ,2FAEE,iBAGF,oCACE,iBCtWN,oBACE,aACA,mBAGF,YACE,oBACA,mBAEA,kLAIE,mBACA,kBACA,eAGF,mBACE,YACA,6GAGF,+BACE,kBCpBF,eACE,qBACA,mBAEA,iBrBEF,OqBD0B,KrBE1B,cANgB,yBAOhB,aqBH+C,OrBI/C,cqBJuE,OrBKvE,UqBL2F,OrBM3F,gBACA,qBACA,oBACA,mBACA,YACA,eACA,0CACA,mBACA,UACA,iBACA,yCAEA,uBACE,uDqBhBA,wBrBqBF,qCACA,6CAEA,4DAEE,qCAGF,8BAEE,qGAGF,8BAEE,qGAkHF,sCACE,gDACA,mBqBpJA,0BrByIF,0EACA,qFACA,oBACA,gBACA,eqBzIE,iBACE,eAIJ,2BACE,qBACA,WAIJ,8CACE,YACE,WAEA,wCAEE,UAGF,qBACE,UACA,gBACA,oBC1CN,gDAEE,kBACA,UACA,oBAGF,0DAEE,kBACA,kBACA,eACA,qBACA,YACA,iBACA,eACA,qBACA,iBAGF,iDAEE,WACA,kBACA,OACA,MACA,WACA,WACA,YACA,UACA,qBAIF,iOAME,kBAGF,6EAEE,wDAGF,sCACE,mBAIF,iCACE,+BAGF,mHAGE,6CAGF,yEAEE,6CAGF,gCACE,sBAIF,yCACE,qBAIF,sCACE,uFAIF,mDACE,qFAGF,kDACE,YACA,qFAIF,0FAEE,+BACA,iFAGF,2BACE,0EAGF,gDACE,iFAGF,yCACE,qFACA,iFC3GA,MACE,sBACA,sBAIJ,qBAEE,wBACA,gBAGA,SACA,kBACA,eAGF,2BACE,gDACA,kBACA,qBAGF,4BACE,UACA,kBACA,cACA,2BACA,4BACA,wDACA,oCACA,WAIF,2BACE,kBACA,cAGA,2BACA,4BAIA,WAEA,oCACA,4BACA,2BAGF,mCACE,6CACA,oIAGF,oCACE,6CACA,8GAIF,qCACE,oBAEF,oCACE,oBAIF,wDAEE,6CAGF,gDAEE,6CAGF,iDACE,qBCrFF,QACE,qBACA,oBACA,oBACA,iBACA,gBACA,kBACA,mFACA,qFAGF,kBAEE,0CACA,iBAGF,cACE,eAGF,mCACE,UACA,QACA,SAIA,kDACE,6CACA,yCAIA,iHACE,kBACA,uFACA,qBACA,sBAEF,wDACE,6CAKN,qBACE,WACA,qBACA,kBACA,yBACA,2BACA,mBACA,iBACA,yCAGA,qDAEA,mBACA,kBACA,+BACA,sBACA,cAGA,uDACE,WACA,kBACA,qBACA,sBACA,uBACA,kBAEA,oBACA,mBAEA,oFAIF,2BACE,6CACA,uBACA,sBAMJ,kLAGI,qBAGJ,iEACE,iFAIF,0IAEE,kFAGF,yDACE,iCAGF,yHAEE,iCAIF,8CACE,eACA,WCpHF,aACE,kBAGF,2CAGE,eAGF,kBACE,kBACA,qGACA,YACA,aACA,WACA,cACA,UACA,WAEA,wBACE,aAIJ,yBACE,kBACA,SACA,OACA,YACA,SACA,QACA,kBACA,6CACA,gBAEA,yBACA,yBAEA,gCACE,cACA,WACA,kBACA,kCACA,YACA,wBAGF,gCACE,4BAEA,uCACE,qCACA,iBACA,eACA,eAsBN,kBACE,gBACA,wBAGF,iDApBE,WACA,qDACA,YAsBF,wCAlBE,YACA,YACA,WACA,kBACA,uCACA,0BAeA,wBACA,6CACA,yBACA,kBAIF,6EACE,uFAQF,oCA1CE,WACA,qDACA,YA4CF,oCACE,SAGF,oCA5CE,YACA,YACA,WACA,kBACA,uCACA,0BAyCA,gBAIF,iCACE,uBACA,oBAGF,yEACE,uFAKF,6BACE,WAEA,yBAEA,2BACA,mBAEA,oBAEF,yEAEE,uCAEF,sEAEE,4CAEF,6BA/EE,YACA,YACA,WACA,kBACA,uCACA,0BA+EF,kEACE,uFCxJF,cACE,6CA0BF,yDACE,kDACA,+CAGF,6HACE,aAGF,uGACE,yBACA,gCAGF,aACE,2CAEA,kBACA,WAIA,yCACE,sBACA,eACA,iBAEA,YACA,kBACA,+DACA,4BACA,6BAEA,qFACE,2CACA,iBAGF,0IACE,0EACA,iFACA,oFAIF,iGACE,yBAEF,ySAKE,sBACA,QAGF,kKACE,0EAkBF,sJAEE,gCAIJ,gCACE,iBAGF,mBACE,6CACA,iBACA,eACA,kBACA,UACA,SACA,YACA,0BACA,WACE,0DAQJ,8BACE,6CACA,eACA,eACA,eAGF,gCACE,6CACA,eACA,YACA,eACA,eAGF,qBACE,kBACA,UACA,SACA,iBACA,aACA,kBAGF,qBACE,kBACA,WACA,SACA,iBAGF,yDACE,kBAEF,yDACE,mBAEF,2BACE,UAUA,2DACE,cACA,+BACA,wDACA,kBAEA,uGACE,oCACA,cACA,iBAKF,mHACE,yBAEF,+VAGE,SACA,UACA,iBACA,cACA,+BAGF,8KACE,0EACA,iFAOJ,qDACE,uCAEF,iGACE,uCAEF,6GACE,gCAEF,yBACE,gCAEF,oCACE,gCAEF,2BACE,gCAMN,QACE,qBAKA,mBACE,kBACA,kBACA,MACA,iBACA,aACA,kBAGF,iBACE,eACA,+BACA,kBAGJ,uBACE,cACA,2CAFF,uBAGI,mBA6BJ,SACE,WACA,YACA,+BAEA,8BACE,4BACA,8BACA,mBACA,kBACA,YACA,gBACA,sBAKJ,WACE,kBACA,qBACA,qBACA,yBACA,mBAEA,kBACA,MACA,WAME,oCACE,wCAGF,6BACE,YACA,WACA,gBAMN,uBACE,kBACA,oBAEA,8BACE,cACA,kBACA,WACA,wBACA,yBACA,cAGF,qCACE,cAGF,2CACE,oBClWJ,uBACE,UACA,wCAMF,OACE,6CACA,WACA,YACA,qDACA,kBACA,YAGF,6BACE,8CACA,kBAGF,gBACE,kBAEA,uBACE,kBACA,QACA,MACA,SACA,cACA,UACA,uCACA,oBAKF,6BACE,QACA,SACA,gBACA,kBACA,MACA,WAIJ,gBACE,qCAIA,+BACE,qCAEF,gCACE,oCAIJ,+CACE,qCACA,eACA,iBAGF,kBACE,qCAGF,4FAGE,qCAMA,wBACE,YACA,WACA,gBACA,iBACA,YAKJ,6BACE,qCACA,2CACE,wCAEF,kCACE,6CAEF,gDACE,kBCrGJ,YACE,aACA,uCACA,SAGA,+BACE,gBAGF,uCAEA,iBACE,YACA,iBAGF,iBACE,eAGF,6BACE,kBACA,MACA,QACA,OACA,SACA,eACA,WACA,SACA,UACA,UACA,eACA,wBAGA,yDACE,aCXN,MACE,qBACA,wBACA,wBACA,6CACA,uBACA,2DACA,6BACA,8CACA,6BACA,2BACA,wBACA,6CACA,2BACA,wBACA,+BACA,gBAEA,+CACA,4EACA,kDACA,4CACA,iDAIF,oBACE,kBACA,oCACA,kCACA,mBACA,sCACA,YACA,8BACA,iBACA,UACA,SACA,aACA,sBACA,qBACA,8BACA,yDAEF,2BACE,2BACA,4BACA,kCACA,SACA,4FACA,YAEA,iBAEF,qDAEE,wGAGA,sBACA,8BACA,UACA,SACA,WACA,mCACA,uCACA,oCACA,mEACA,YACA,mBACA,aACA,gBAGF,2BACE,UAEA,oEAEA,UAEF,kCACE,uBACA,YAEF,uCACE,2BACA,8BAEF,0BACE,kBACA,+EACA,2DACA,8BACA,YACA,iBACA,kBAEA,UACA,oBAIF,oCACE,wBAIF,4CACE,WACA,kBACA,cACA,2CACA,uCACA,SACA,6DACA,kBACA,wDAEF,oCACE,kBAEF,gDACE,UACA,0DAEF,mCACE,kBACA,8DACA,8BACA,WACE,+HAKJ,+EACE,QAEF,uEACE,2BAEF,sEACE,kBAIF,0BACE,0CACA,mCACA,+DAEF,yCACE,0CACA,mCAEF,iCACE,4BAGF,0CACE,kBAEF,mFACE,kBAEF,6EACE,4BAEF,yCAEE,4BACA,oEACA,gHAOF,iCACE,0CACA,mCACA,+DAEF,gDACE,0CACA,mCAEF,wCACE,4BAEF,iCACE,4BAGF,yDACE,QAEF,iDACE,4BAEF,oFACE,4BAEF,6DACE,kBAEF,gDACE,kBACA,oEA+BF,kEAEE,6BACA,sCACA,iBACA,mBACA,yDAEF,oCACE,mBAEF,sFAEE,+BACA,mBAEF,oCACE,mFACA,oCAEF,oCACE,oCAEF,qFAEE,mEAEF,2CACE,4FACA,yBACA,sCACA,+BACA,mBAEF,oCACE,mBAIF,kDACE,aAEF,iDACE","file":"materialize.min.css"} \ No newline at end of file diff --git a/dist/js/materialize.cjs.js b/dist/js/materialize.cjs.js deleted file mode 100644 index 5fe3fef53c..0000000000 --- a/dist/js/materialize.cjs.js +++ /dev/null @@ -1,8404 +0,0 @@ -/*! -* Materialize v2.3.3 (https://materializeweb.com) -* Copyright 2014-2026 Materialize -* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE) -*/ -'use strict'; - -/** - * Class with utilitary functions for global usage. - */ -class Utils { - /** Specifies wether tab is pressed or not. */ - static tabPressed = false; - /** Specifies wether there is a key pressed. */ - static keyDown = false; - /** - * Key maps. - */ - static keys = { - TAB: ['Tab'], - ENTER: ['Enter'], - ESC: ['Escape', 'Esc'], - BACKSPACE: ['Backspace'], - ARROW_UP: ['ArrowUp', 'Up'], - ARROW_DOWN: ['ArrowDown', 'Down'], - ARROW_LEFT: ['ArrowLeft', 'Left'], - ARROW_RIGHT: ['ArrowRight', 'Right'], - DELETE: ['Delete', 'Del'] - }; - /** - * Detects when a key is pressed. - * @param e Event instance. - */ - static docHandleKeydown(e) { - Utils.keyDown = true; - if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) { - Utils.tabPressed = true; - } - } - /** - * Detects when a key is released. - * @param e Event instance. - */ - static docHandleKeyup(e) { - Utils.keyDown = false; - if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) { - Utils.tabPressed = false; - } - } - /** - * Detects when document is focused. - * @param e Event instance. - */ - /* eslint-disabled as of required event type condition check */ - /* eslint-disable-next-line */ - static docHandleFocus(e) { - if (Utils.keyDown) { - document.body.classList.add('keyboard-focused'); - } - } - /** - * Detects when document is not focused. - * @param e Event instance. - */ - /* eslint-disabled as of required event type condition check */ - /* eslint-disable-next-line */ - static docHandleBlur(e) { - document.body.classList.remove('keyboard-focused'); - } - /** - * Generates a unique string identifier. - */ - static guid() { - const s4 = () => { - return Math.floor((1 + Math.random()) * 0x10000) - .toString(16) - .substring(1); - }; - return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); - } - /** - * Checks for exceeded edges - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkWithinContainer(container, bounding, offset) { - const edges = { - top: false, - right: false, - bottom: false, - left: false - }; - const containerRect = container.getBoundingClientRect(); - // If body element is smaller than viewport, use viewport height instead. - const containerBottom = container === document.body - ? Math.max(containerRect.bottom, window.innerHeight) - : containerRect.bottom; - const scrollLeft = container.scrollLeft; - const scrollTop = container.scrollTop; - const scrolledX = bounding.left - scrollLeft; - const scrolledY = bounding.top - scrollTop; - // Check for container and viewport for each edge - if (scrolledX < containerRect.left + offset || scrolledX < offset) { - edges.left = true; - } - if (scrolledX + bounding.width > containerRect.right - offset || - scrolledX + bounding.width > window.innerWidth - offset) { - edges.right = true; - } - if (scrolledY < containerRect.top + offset || scrolledY < offset) { - edges.top = true; - } - if (scrolledY + bounding.height > containerBottom - offset || - scrolledY + bounding.height > window.innerHeight - offset) { - edges.bottom = true; - } - return edges; - } - /** - * Checks if element can be aligned in multiple directions. - * @param el Element to be inspected. - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkPossibleAlignments(el, container, bounding, offset) { - const canAlign = { - top: true, - right: true, - bottom: true, - left: true, - spaceOnTop: null, - spaceOnRight: null, - spaceOnBottom: null, - spaceOnLeft: null - }; - const containerAllowsOverflow = getComputedStyle(container).overflow === 'visible'; - const containerRect = container.getBoundingClientRect(); - const containerHeight = Math.min(containerRect.height, window.innerHeight); - const containerWidth = Math.min(containerRect.width, window.innerWidth); - const elOffsetRect = el.getBoundingClientRect(); - const scrollLeft = container.scrollLeft; - const scrollTop = container.scrollTop; - const scrolledX = bounding.left - scrollLeft; - const scrolledYTopEdge = bounding.top - scrollTop; - const scrolledYBottomEdge = bounding.top + elOffsetRect.height - scrollTop; - // Check for container and viewport for left - canAlign.spaceOnRight = !containerAllowsOverflow - ? containerWidth - (scrolledX + bounding.width) - : window.innerWidth - (elOffsetRect.left + bounding.width); - if (canAlign.spaceOnRight < 0) { - canAlign.left = false; - } - // Check for container and viewport for Right - canAlign.spaceOnLeft = !containerAllowsOverflow - ? scrolledX - bounding.width + elOffsetRect.width - : elOffsetRect.right - bounding.width; - if (canAlign.spaceOnLeft < 0) { - canAlign.right = false; - } - // Check for container and viewport for Top - canAlign.spaceOnBottom = !containerAllowsOverflow - ? containerHeight - (scrolledYTopEdge + bounding.height + offset) - : window.innerHeight - (elOffsetRect.top + bounding.height + offset); - if (canAlign.spaceOnBottom < 0) { - canAlign.top = false; - } - // Check for container and viewport for Bottom - canAlign.spaceOnTop = !containerAllowsOverflow - ? scrolledYBottomEdge - (bounding.height - offset) - : elOffsetRect.bottom - (bounding.height + offset); - if (canAlign.spaceOnTop < 0) { - canAlign.bottom = false; - } - return canAlign; - } - /** - * Retrieves target element id from trigger. - * @param trigger Trigger element. - */ - static getIdFromTrigger(trigger) { - let id = trigger.dataset.target; - if (!id) { - id = trigger.getAttribute('href'); - return id ? id.slice(1) : ''; - } - return id; - } - /** - * Retrieves document scroll postion from top. - */ - static getDocumentScrollTop() { - return window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0; - } - /** - * Retrieves document scroll postion from left. - */ - static getDocumentScrollLeft() { - return window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft || 0; - } - /** - * Fires the given function after a certain ammount of time. - * @param func Function to be fired. - * @param wait Wait time. - * @param options Additional options. - */ - static throttle(func, wait, options = {}) { - let context, args, result, timeout = null, previous = 0; - const later = () => { - previous = options.leading === false ? 0 : new Date().getTime(); - timeout = null; - result = func.apply(context, args); - context = args = null; - }; - return (...args) => { - const now = new Date().getTime(); - if (!previous && options.leading === false) - previous = now; - const remaining = wait - (now - previous); - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(this, args); - } - else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - } - /** - * Renders confirm/close buttons with callback function - */ - static createConfirmationContainer(container, confirmText, cancelText, onConfirm, onCancel) { - const confirmationButtonsContainer = document.createElement('div'); - confirmationButtonsContainer.classList.add('confirmation-btns'); - container.append(confirmationButtonsContainer); - this.createButton(confirmationButtonsContainer, cancelText, ['btn-cancel'], true, onCancel); - this.createButton(confirmationButtonsContainer, confirmText, ['btn-confirm'], true, onConfirm); - } - /** - * Renders a button with optional callback function - */ - static createButton(container, text, className = [], visibility = true, callback = null) { - className = className.concat(['btn', 'waves-effect', 'text']); - const button = document.createElement('button'); - button.className = className.join(' '); - button.style.visibility = visibility ? 'visible' : 'hidden'; - button.type = 'button'; - button.tabIndex = !!visibility ? 0 : -1; - button.innerText = text; - button.addEventListener('click', callback); - button.addEventListener('keypress', (e) => { - if (Utils.keys.ENTER.includes(e.key)) - callback(e); - }); - container.append(button); - } - static _setAbsolutePosition(origin, container, position, margin, transitionMovement, align = 'center') { - const originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, containerHeight = container.offsetHeight, containerWidth = container.offsetWidth; - let xMovement = 0, yMovement = 0, targetTop = origin.getBoundingClientRect().top + Utils.getDocumentScrollTop(), targetLeft = origin.getBoundingClientRect().left + Utils.getDocumentScrollLeft(); - if (position === 'top') { - targetTop += -containerHeight - margin; - if (align === 'center') { - targetLeft += originWidth / 2 - containerWidth / 2; // This is center align - } - yMovement = -transitionMovement; - } - else if (position === 'right') { - targetTop += originHeight / 2 - containerHeight / 2; - targetLeft = originWidth + margin; - xMovement = transitionMovement; - } - else if (position === 'left') { - targetTop += originHeight / 2 - containerHeight / 2; - targetLeft = -containerWidth - margin; - xMovement = -transitionMovement; - } - else { - targetTop += originHeight + margin; - if (align === 'center') { - targetLeft += originWidth / 2 - containerWidth / 2; // This is center align - } - yMovement = transitionMovement; - } - if (align === 'right') { - targetLeft += originWidth - containerWidth - margin; - } - const newCoordinates = Utils._repositionWithinScreen(targetLeft, targetTop, containerWidth, containerHeight, margin, transitionMovement, align); - container.style.top = newCoordinates.y + 'px'; - container.style.left = newCoordinates.x + 'px'; - return { x: xMovement, y: yMovement }; - } - static _repositionWithinScreen(x, y, width, height, margin, transitionMovement, align) { - const scrollLeft = Utils.getDocumentScrollLeft(); - const scrollTop = Utils.getDocumentScrollTop(); - let newX = x - scrollLeft; - let newY = y - scrollTop; - const bounding = { - left: newX, - top: newY, - width: width, - height: height - }; - let offset; - if (align === 'left' || align == 'center') { - offset = margin + transitionMovement; - } - else if (align === 'right') { - offset = margin - transitionMovement; - } - const edges = Utils.checkWithinContainer(document.body, bounding, offset); - if (edges.left) { - newX = offset; - } - else if (edges.right) { - newX -= newX + width - window.innerWidth; - } - if (edges.top) { - newY = offset; - } - else if (edges.bottom) { - newY -= newY + height - window.innerHeight; - } - return { - x: newX + scrollLeft, - y: newY + scrollTop - }; - } -} - -/** - * Base class implementation for Materialize components. - */ -class Component { - /** - * The DOM element the plugin was initialized with. - */ - el; - /** - * The options the instance was initialized with. - */ - options; - /** - * Constructs component instance and set everything up. - */ - constructor(el, options, classDef) { - // Display error if el is not a valid HTML Element - if (!(el instanceof HTMLElement)) { - console.error(Error(el + ' is not an HTML Element')); - } - // If exists, destroy and reinitialize in child - const ins = classDef.getInstance(el); - if (!!ins) { - ins.destroy(); - } - this.el = el; - } - /** - * Initializes component instances. - * @param els HTML elements. - * @param options Component options. - * @param classDef Class definition. - */ - static init(els, options, classDef) { - let instances = null; - if (els instanceof Element) { - instances = new classDef(els, options); - } - else if (!!els && els.length) { - instances = []; - for (let i = 0; i < els.length; i++) { - instances.push(new classDef(els[i], options)); - } - } - return instances; - } - /** - * @returns default options for component instance. - */ - static get defaults() { - return {}; - } - /** - * Retrieves component instance for the given element. - * @param el Associated HTML Element. - */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - static getInstance(el) { - throw new Error('This method must be implemented.'); - } - /** - * Destroy plugin instance and teardown. - */ - destroy() { - throw new Error('This method must be implemented.'); - } -} - -const _defaults$o = { - alignment: 'left', - autoFocus: true, - constrainWidth: true, - container: null, - coverTrigger: true, - closeOnClick: true, - hover: false, - inDuration: 150, - outDuration: 250, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - onItemClick: null -}; -class Dropdown extends Component { - static _dropdowns = []; - /** ID of the dropdown element. */ - id; - /** The DOM element of the dropdown. */ - dropdownEl; - /** If the dropdown is open. */ - isOpen; - /** If the dropdown content is scrollable. */ - isScrollable; - isTouchMoving; - /** The index of the item focused. */ - focusedIndex; - filterQuery; - filterTimeout; - constructor(el, options) { - super(el, options, Dropdown); - this.el['M_Dropdown'] = this; - Dropdown._dropdowns.push(this); - this.id = Utils.getIdFromTrigger(el); - this.dropdownEl = document.getElementById(this.id); - this.options = { - ...Dropdown.defaults, - ...options - }; - this.isOpen = false; - this.isScrollable = false; - this.isTouchMoving = false; - this.focusedIndex = -1; - this.filterQuery = []; - this.el.ariaExpanded = 'false'; - // Move dropdown-content after dropdown-trigger - this._moveDropdownToElement(); - this._makeDropdownFocusable(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$o; - } - /** - * Initializes instances of Dropdown. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Dropdown); - } - static getInstance(el) { - return el['M_Dropdown']; - } - destroy() { - this._resetDropdownStyles(); - this._removeEventHandlers(); - Dropdown._dropdowns.splice(Dropdown._dropdowns.indexOf(this), 1); - this.el['M_Dropdown'] = undefined; - } - _setupEventHandlers() { - // Trigger keydown handler - this.el.addEventListener('keydown', this._handleTriggerKeydown); - // Item click handler - this.dropdownEl?.addEventListener('click', this._handleDropdownClick); - // Hover event handlers - if (this.options.hover) { - this.el.addEventListener('mouseenter', this._handleMouseEnter); - this.el.addEventListener('mouseleave', this._handleMouseLeave); - this.dropdownEl.addEventListener('mouseleave', this._handleMouseLeave); - // Click event handlers - } - else { - this.el.addEventListener('click', this._handleClick); - } - } - _removeEventHandlers() { - this.el.removeEventListener('keydown', this._handleTriggerKeydown); - this.dropdownEl.removeEventListener('click', this._handleDropdownClick); - if (this.options.hover) { - this.el.removeEventListener('mouseenter', this._handleMouseEnter); - this.el.removeEventListener('mouseleave', this._handleMouseLeave); - this.dropdownEl.removeEventListener('mouseleave', this._handleMouseLeave); - } - else { - this.el.removeEventListener('click', this._handleClick); - } - } - _setupTemporaryEventHandlers() { - document.body.addEventListener('click', this._handleDocumentClick); - document.body.addEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.addEventListener('keydown', this._handleDropdownKeydown); - window.addEventListener('resize', this._handleWindowResize); - } - _removeTemporaryEventHandlers() { - document.body.removeEventListener('click', this._handleDocumentClick); - document.body.removeEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.removeEventListener('keydown', this._handleDropdownKeydown); - window.removeEventListener('resize', this._handleWindowResize); - } - _handleClick = (e) => { - e.preventDefault(); - //this._moveDropdown((e.target).closest('li')); - if (this.isOpen) { - this.close(); - } - else { - this.open(); - } - }; - _handleMouseEnter = () => { - //this._moveDropdown((e.target).closest('li')); - this.open(); - }; - _handleMouseLeave = (e) => { - const toEl = e.relatedTarget; - const leaveToDropdownContent = !!toEl.closest('.dropdown-content'); - let leaveToActiveDropdownTrigger = false; - const closestTrigger = toEl.closest('.dropdown-trigger'); - if (closestTrigger && !!closestTrigger['M_Dropdown'] && closestTrigger['M_Dropdown'].isOpen) { - leaveToActiveDropdownTrigger = true; - } - // Close hover dropdown if mouse did not leave to either active dropdown-trigger or dropdown-content - if (!leaveToActiveDropdownTrigger && !leaveToDropdownContent) { - this.close(); - } - }; - _handleDocumentClick = (e) => { - const target = e.target; - if (this.options.closeOnClick && target.closest('.dropdown-content') && !this.isTouchMoving) { - // isTouchMoving to check if scrolling on mobile. - this.close(); - } - else if (!target.closest('.dropdown-content')) { - // Do this one frame later so that if the element clicked also triggers _handleClick - // For example, if a label for a select was clicked, that we don't close/open the dropdown - setTimeout(() => { - if (this.isOpen) { - this.close(); - } - }, 0); - } - this.isTouchMoving = false; - }; - _handleTriggerKeydown = (e) => { - // ARROW DOWN OR ENTER WHEN SELECT IS CLOSED - open Dropdown - const arrowDownOrEnter = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ENTER.includes(e.key); - if (arrowDownOrEnter && !this.isOpen) { - e.preventDefault(); - this.open(); - } - }; - _handleDocumentTouchmove = (e) => { - const target = e.target; - if (target.closest('.dropdown-content')) { - this.isTouchMoving = true; - } - }; - _handleDropdownClick = (e) => { - // onItemClick callback - if (typeof this.options.onItemClick === 'function') { - const itemEl = e.target.closest('li'); - this.options.onItemClick.call(this, itemEl); - } - }; - _handleDropdownKeydown = (e) => { - const arrowUpOrDown = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ARROW_UP.includes(e.key); - if (Utils.keys.TAB.includes(e.key)) { - e.preventDefault(); - this.close(); - } - // Navigate down dropdown list - else if (arrowUpOrDown && this.isOpen) { - e.preventDefault(); - const direction = Utils.keys.ARROW_DOWN.includes(e.key) ? 1 : -1; - let newFocusedIndex = this.focusedIndex; - let hasFoundNewIndex = false; - do { - newFocusedIndex = newFocusedIndex + direction; - if (!!this.dropdownEl.children[newFocusedIndex] && - this.dropdownEl.children[newFocusedIndex].tabIndex !== -1) { - hasFoundNewIndex = true; - break; - } - } while (newFocusedIndex < this.dropdownEl.children.length && newFocusedIndex >= 0); - if (hasFoundNewIndex) { - // Remove active class from old element - if (this.focusedIndex >= 0) - this.dropdownEl.children[this.focusedIndex].classList.remove('active'); - this.focusedIndex = newFocusedIndex; - this._focusFocusedItem(); - } - } - // ENTER selects choice on focused item - else if (Utils.keys.ENTER.includes(e.key) && this.isOpen) { - // Search for and ` + - ''); - } - renderRow(days, isRTL, isRowSelected) { - return ('' + - (isRTL ? days.reverse() : days).join('') + - ''); - } - renderTable(opts, data, randId) { - return ('
' + - this.renderHead(opts) + - this.renderBody(data) + - '
'); - } - renderHead(opts) { - const arr = []; - let i; - for (i = 0; i < 7; i++) { - arr.push(`${this.renderDayName(opts, i, true)}`); - } - return '' + (opts.isRTL ? arr.reverse() : arr).join('') + ''; - } - renderBody(rows) { - return '' + rows.join('') + ''; - } - renderTitle(instance, c, year, month, refYear, randId) { - const opts = this.options, isMinYear = year === opts.minYear, isMaxYear = year === opts.maxYear; - let i, j, arr = [], html = '
', prev = true, next = true; - for (i = 0; i < 12; i++) { - arr.push(''); - } - const monthHtml = ''; - if (Array.isArray(opts.yearRange)) { - i = opts.yearRange[0]; - j = opts.yearRange[1] + 1; - } - else { - i = year - opts.yearRange; - j = 1 + year + opts.yearRange; - } - for (arr = []; i < j && i <= opts.maxYear; i++) { - if (i >= opts.minYear) { - arr.push(``); - } - } - if (opts.yearRangeReverse) - arr.reverse(); - const yearHtml = ``; - const leftArrow = ''; - html += ``; - html += '
'; - if (opts.showMonthAfterYear) { - html += yearHtml + monthHtml; - } - else { - html += monthHtml + yearHtml; - } - html += '
'; - if (isMinYear && (month === 0 || opts.minMonth >= month)) { - prev = false; - } - if (isMaxYear && (month === 11 || opts.maxMonth <= month)) { - next = false; - } - const rightArrow = ''; - html += ``; - return (html += '
'); - } - // refresh HTML - draw() { - const opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth; - let html = ''; - if (this._y <= minYear) { - this._y = minYear; - if (!isNaN(minMonth) && this._m < minMonth) { - this._m = minMonth; - } - } - if (this._y >= maxYear) { - this._y = maxYear; - if (!isNaN(maxMonth) && this._m > maxMonth) { - this._m = maxMonth; - } - } - const randId = 'datepicker-title-' + - Math.random() - .toString(36) - .replace(/[^a-z]+/g, '') - .substr(0, 2); - for (let c = 0; c < 1; c++) { - if (!this.options.isDateRange) { - this._renderDateDisplay(this.date); - } - else { - this._renderDateDisplay(this.date, this.endDate); - } - html += - this.renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId); - } - this.destroySelects(); - this.calendarEl.innerHTML = html; - // Init Materialize Select - const yearSelect = this.calendarEl.querySelector('.orig-select-year'); - const monthSelect = this.calendarEl.querySelector('.orig-select-month'); - // @todo fix accessibility @see https://github.com/materializecss/materialize/issues/522 - FormSelect.init(yearSelect, { - classes: 'select-year', - dropdownOptions: { container: document.body, constrainWidth: false } - }); - FormSelect.init(monthSelect, { - classes: 'select-month', - dropdownOptions: { container: document.body, constrainWidth: false } - }); - // Add change handlers for select - yearSelect.addEventListener('change', this._handleYearChange); - monthSelect.addEventListener('change', this._handleMonthChange); - if (typeof this.options.onDraw === 'function') { - this.options.onDraw.call(this); - } - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleInputClick); - this.el.addEventListener('keydown', this._handleInputKeydown); - this.el.addEventListener('change', this._handleInputChange); - this.calendarEl.addEventListener('click', this._handleCalendarClick); - } - _setupVariables() { - const template = document.createElement('template'); - template.innerHTML = Datepicker._template.trim(); - this.containerEl = template.content.firstChild; - this.calendarEl = this.containerEl.querySelector('.datepicker-calendar'); - this.yearTextEl = this.containerEl.querySelector('.year-text'); - this.dateTextEl = this.containerEl.querySelector('.date-text'); - this.footer = this.containerEl.querySelector('.datepicker-footer'); - this.formats = { - d: (date) => { - return date.getDate(); - }, - dd: (date) => { - const d = date.getDate(); - return (d < 10 ? '0' : '') + d; - }, - ddd: (date) => { - return this.options.i18n.weekdaysShort[date.getDay()]; - }, - dddd: (date) => { - return this.options.i18n.weekdays[date.getDay()]; - }, - m: (date) => { - return date.getMonth() + 1; - }, - mm: (date) => { - const m = date.getMonth() + 1; - return (m < 10 ? '0' : '') + m; - }, - mmm: (date) => { - return this.options.i18n.monthsShort[date.getMonth()]; - }, - mmmm: (date) => { - return this.options.i18n.months[date.getMonth()]; - }, - yy: (date) => { - return ('' + date.getFullYear()).slice(2); - }, - yyyy: (date) => { - return date.getFullYear(); - } - }; - } - _pickerSetup() { - if (!this.options.defaultDate) { - this.options.defaultDate = new Date(Date.parse(this.el.value)); - } - const defDate = this.options.defaultDate; - if (Datepicker._isDate(defDate)) { - if (this.options.setDefaultDate) { - this.setDate(defDate, true); - this.setInputValue(this.el, defDate); - } - else { - this.gotoDate(defDate); - } - } - else { - this.gotoDate(new Date()); - } - if (this.options.isDateRange) { - this.multiple = true; - const defEndDate = this.options.defaultEndDate; - if (Datepicker._isDate(defEndDate)) { - if (this.options.setDefaultEndDate) { - this.setDate(defEndDate, true, true); - this.setInputValue(this.endDateEl, defEndDate); - } - } - } - if (this.options.isMultipleSelection) { - this.multiple = true; - this.dates = []; - this.dateEls = []; - this.dateEls.push(this.el); - } - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleInputClick); - this.el.removeEventListener('keydown', this._handleInputKeydown); - this.el.removeEventListener('change', this._handleInputChange); - this.calendarEl.removeEventListener('click', this._handleCalendarClick); - if (this.options.isDateRange) { - this.endDateEl.removeEventListener('click', this._handleInputClick); - this.endDateEl.removeEventListener('keypress', this._handleInputKeydown); - this.endDateEl.removeEventListener('change', this._handleInputChange); - } - } - _handleInputClick = (e) => { - // Prevents default browser datepicker modal rendering - if (e.type == 'date') { - e.preventDefault(); - } - this.setDateFromInput(e.target); - this.draw(); - this.gotoDate(e.target === this.el ? this.date : this.endDate); - if (this.displayPlugin) - this.displayPlugin.show(); - if (this.options.onInputInteraction) - this.options.onInputInteraction.call(this); - }; - _handleInputKeydown = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this.setDateFromInput(e.target); - this.draw(); - if (this.displayPlugin) - this.displayPlugin.show(); - if (this.options.onInputInteraction) - this.options.onInputInteraction.call(this); - } - }; - _handleCalendarClick = (e) => { - const target = e.target; - if (!target.classList.contains('is-disabled')) { - if (target.classList.contains('datepicker-day-button') && - !target.classList.contains('is-empty') && - !target.parentElement.classList.contains('is-disabled')) { - const selectedDate = new Date(e.target.getAttribute('data-year'), e.target.getAttribute('data-month'), e.target.getAttribute('data-day')); - if (!this.multiple || (this.multiple && this.options.isMultipleSelection)) { - this.setDate(selectedDate); - } - if (this.options.isDateRange) { - const confirmAfterSelection = Datepicker._isDate(this.date) && this.options.autoSubmit; - this._handleDateRangeCalendarClick(selectedDate); - if (confirmAfterSelection) { - this._confirm(); - } - } - if (!this.options.isDateRange && this.options.autoSubmit) - this._confirm(); - } - else if (target.closest('.month-prev')) { - this.prevMonth(); - } - else if (target.closest('.month-next')) { - this.nextMonth(); - } - } - }; - _handleDateRangeCalendarClick = (date) => { - if (this.endDate == null || !Datepicker._compareDates(date, this.endDate)) { - if (Datepicker._isDate(this.date) && Datepicker._comparePastDate(date, this.date)) { - return; - } - this.setDate(date, true, Datepicker._isDate(this.date)); - return; - } - this._clearDates(); - this.draw(); - }; - _handleClearClick = () => { - this._clearDates(); - this.setInputValues(); - }; - _clearDates = () => { - this.date = null; - this.endDate = null; - this.draw(); - }; - _handleMonthChange = (e) => { - this.gotoMonth(e.target.value); - }; - _handleYearChange = (e) => { - this.gotoYear(e.target.value); - }; - // change view to a specific month (zero-index, e.g. 0: January) - gotoMonth(month) { - if (!isNaN(month)) { - this.calendars[0].month = parseInt(month, 10); - this.adjustCalendars(); - } - } - // change view to a specific full year (e.g. "2012") - gotoYear(year) { - if (!isNaN(year)) { - this.calendars[0].year = parseInt(year, 10); - this.adjustCalendars(); - } - } - _handleInputChange = (e) => { - let date; - const el = e.target; - // Prevent change event from being fired when triggered by the plugin - if (e['detail']?.firedBy === this) - return; - // Prevent change event from being fired if an end date is set without a start date - if (el == this.endDateEl && !this.date) - return; - if (this.options.parse) { - date = this.options.parse(e.target.value, typeof this.options.format === 'function' - ? this.options.format(new Date(this.el.value)) - : this.options.format); - } - else { - date = new Date(Date.parse(e.target.value)); - } - if (Datepicker._isDate(date)) { - this.setDate(date, false, el == this.endDateEl, true); - if (e.type == 'date') { - this.setDataDate(e, date); - this.setInputValues(); - } - } - }; - renderDayName(opts, day, abbr = false) { - day += opts.firstDay; - while (day >= 7) { - day -= 7; - } - return abbr ? opts.i18n.weekdaysAbbrev[day] : opts.i18n.weekdays[day]; - } - createDateInput() { - const dateInput = this.el.cloneNode(true); - dateInput.addEventListener('click', this._handleInputClick); - dateInput.addEventListener('keypress', this._handleInputKeydown); - dateInput.addEventListener('change', this._handleInputChange); - this.el.parentElement.appendChild(dateInput); - return dateInput; - } - // Set input value to the selected date and close Datepicker - _finishSelection = () => { - this.setInputValues(); - // Commented out because of function deprecations - // this.close(); - }; - _confirm = () => { - this._finishSelection(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onConfirm === 'function') - this.options.onConfirm.call(this); - }; - _cancel = () => { - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onCancel === 'function') - this.options.onCancel.call(this); - }; - // deprecated - open() { - console.warn('Datepicker.open() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - close() { - console.warn('Datepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - static { - Datepicker._template = ` -
-
- - -
-
-
- -
-
`; - } -} - -class Forms { - /** - * Checks if the label has validation and apply - * the correct class and styles - * @param textfield - */ - static validateField(textfield) { - if (!textfield) { - console.error('No text field element found'); - return; - } - const hasLength = textfield.getAttribute('data-length') !== null; - const lenAttr = parseInt(textfield.getAttribute('data-length')); - const len = textfield.value.length; - if (len === 0 && - textfield.validity.badInput === false && - !textfield.required && - textfield.classList.contains('validate')) { - textfield.classList.remove('invalid'); - } - else if (textfield.classList.contains('validate')) { - // Check for character counter attributes - if ((textfield.validity.valid && hasLength && len <= lenAttr) || - (textfield.validity.valid && !hasLength)) { - textfield.classList.remove('invalid'); - } - else { - textfield.classList.add('invalid'); - } - } - } - /** - * Resizes the given TextArea after updating the - * value content dynamically. - * @param e EventTarget - */ - static textareaAutoResize(e) { - const textarea = e; - // if (!textarea) { - // console.error('No textarea element found'); - // return; - // } - // Textarea Auto Resize - let hiddenDiv = document.querySelector('.hiddendiv'); - if (!hiddenDiv) { - hiddenDiv = document.createElement('div'); - hiddenDiv.classList.add('hiddendiv', 'common'); - document.body.append(hiddenDiv); - } - const style = getComputedStyle(textarea); - // Set font properties of hiddenDiv - const fontFamily = style.fontFamily; //textarea.css('font-family'); - const fontSize = style.fontSize; //textarea.css('font-size'); - const lineHeight = style.lineHeight; //textarea.css('line-height'); - // Firefox can't handle padding shorthand. - const paddingTop = style.paddingTop; //getComputedStyle(textarea).css('padding-top'); - const paddingRight = style.paddingRight; //textarea.css('padding-right'); - const paddingBottom = style.paddingBottom; //textarea.css('padding-bottom'); - const paddingLeft = style.paddingLeft; //textarea.css('padding-left'); - if (fontSize) - hiddenDiv.style.fontSize = fontSize; //('font-size', fontSize); - if (fontFamily) - hiddenDiv.style.fontFamily = fontFamily; //css('font-family', fontFamily); - if (lineHeight) - hiddenDiv.style.lineHeight = lineHeight; //css('line-height', lineHeight); - if (paddingTop) - hiddenDiv.style.paddingTop = paddingTop; //ss('padding-top', paddingTop); - if (paddingRight) - hiddenDiv.style.paddingRight = paddingRight; //css('padding-right', paddingRight); - if (paddingBottom) - hiddenDiv.style.paddingBottom = paddingBottom; //css('padding-bottom', paddingBottom); - if (paddingLeft) - hiddenDiv.style.paddingLeft = paddingLeft; //css('padding-left', paddingLeft); - // Set original-height, if none - if (!textarea.hasAttribute('original-height')) - textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString()); - if (textarea.getAttribute('wrap') === 'off') { - hiddenDiv.style.overflowWrap = 'normal'; // ('overflow-wrap', 'normal') - hiddenDiv.style.whiteSpace = 'pre'; //.css('white-space', 'pre'); - } - hiddenDiv.innerText = textarea.value + '\n'; - hiddenDiv.innerHTML = hiddenDiv.innerHTML.replace(/\n/g, '
'); - // When textarea is hidden, width goes crazy. - // Approximate with half of window size - if (textarea.offsetWidth > 0 && textarea.offsetHeight > 0) { - hiddenDiv.style.width = textarea.getBoundingClientRect().width + 'px'; // ('width', textarea.width() + 'px'); - } - else { - hiddenDiv.style.width = window.innerWidth / 2 + 'px'; //css('width', window.innerWidth / 2 + 'px'); - } - // Resize if the new height is greater than the - // original height of the textarea - const originalHeight = parseInt(textarea.getAttribute('original-height')); - const prevLength = parseInt(textarea.getAttribute('previous-length')); - if (isNaN(originalHeight)) - return; - if (originalHeight <= hiddenDiv.clientHeight) { - textarea.style.height = hiddenDiv.clientHeight + 'px'; //css('height', hiddenDiv.innerHeight() + 'px'); - } - else if (textarea.value.length < prevLength) { - // In case the new height is less than original height, it - // means the textarea has less text than before - // So we set the height to the original one - textarea.style.height = originalHeight + 'px'; - } - textarea.setAttribute('previous-length', (textarea.value || '').length.toString()); - } - static Init() { - if (typeof document !== 'undefined') - document?.addEventListener('DOMContentLoaded', () => { - document.addEventListener('change', (e) => { - const target = e.target; - if (target instanceof HTMLInputElement) { - if (target.value.length !== 0 || target.getAttribute('placeholder') !== null) { - for (const child of target.parentNode.children) { - if (child.tagName == 'label') { - child.classList.add('active'); - } - } - } - Forms.validateField(target); - } - }); - document.addEventListener('keyup', (e) => { - const target = e.target; - // Radio and Checkbox focus class - if (target instanceof HTMLInputElement && ['radio', 'checkbox'].includes(target.type)) { - // TAB, check if tabbing to radio or checkbox. - if (Utils.keys.TAB.includes(e.key)) { - target.classList.add('tabbed'); - target.addEventListener('blur', () => target.classList.remove('tabbed'), { - once: true - }); - } - } - }); - document - .querySelectorAll('.materialize-textarea') - .forEach((textArea) => { - Forms.InitTextarea(textArea); - }); - // File Input Path - document - .querySelectorAll('.file-field input[type="file"]') - .forEach((fileInput) => { - Forms.InitFileInputPath(fileInput); - }); - }); - } - static InitTextarea(textarea) { - // Save Data in Element - textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString()); - textarea.setAttribute('previous-length', (textarea.value || '').length.toString()); - Forms.textareaAutoResize(textarea); - textarea.addEventListener('keyup', (e) => Forms.textareaAutoResize(e.target)); - textarea.addEventListener('keydown', (e) => Forms.textareaAutoResize(e.target)); - } - static InitFileInputPath(fileInput) { - fileInput.addEventListener('change', () => { - const fileField = fileInput.closest('.file-field'); - const pathInput = fileField.querySelector('input.file-path'); - const files = fileInput.files; - const filenames = []; - for (let i = 0; i < files.length; i++) { - filenames.push(files[i].name); - } - pathInput.value = filenames.join(', '); - pathInput.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); - }); - } -} - -const _defaults$d = { - inDuration: 275, - outDuration: 200, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null -}; -class Materialbox extends Component { - /** If the materialbox overlay is showing. */ - overlayActive; - /** If the materialbox is no longer being animated. */ - doneAnimating; - /** Caption, if specified. */ - caption; - /** Original width of image. */ - originalWidth; - /** Original height of image. */ - originalHeight; - originInlineStyles; - placeholder; - _changedAncestorList; - newHeight; - newWidth; - windowWidth; - windowHeight; - attrWidth; - attrHeight; - _overlay; - _photoCaption; - constructor(el, options) { - super(el, options, Materialbox); - this.el['M_Materialbox'] = this; - this.options = { - ...Materialbox.defaults, - ...options - }; - this.overlayActive = false; - this.doneAnimating = true; - this.placeholder = document.createElement('div'); - this.placeholder.classList.add('material-placeholder'); - this.originalWidth = 0; - this.originalHeight = 0; - this.originInlineStyles = this.el.getAttribute('style'); - this.caption = this.el.getAttribute('data-caption') || ''; - this.el.tabIndex = 0; - // Wrap - this.el.before(this.placeholder); - this.placeholder.append(this.el); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$d; - } - /** - * Initializes instances of MaterialBox. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Materialbox); - } - static getInstance(el) { - return el['M_Materialbox']; - } - destroy() { - this._removeEventHandlers(); - this.el['M_Materialbox'] = undefined; - // Unwrap image - //this.placeholder.after(this.el).remove(); - this.placeholder.remove(); - this.el.removeAttribute('style'); - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleMaterialboxClick); - this.el.addEventListener('keypress', this._handleMaterialboxKeypress); - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleMaterialboxClick); - this.el.removeEventListener('keypress', this._handleMaterialboxKeypress); - } - _handleMaterialboxClick = () => { - this._handleMaterialboxToggle(); - }; - _handleMaterialboxKeypress = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleMaterialboxToggle(); - } - }; - _handleMaterialboxToggle = () => { - // If already modal, return to original - if (this.doneAnimating === false || (this.overlayActive && this.doneAnimating)) - this.close(); - else - this.open(); - }; - _handleWindowScroll = () => { - if (this.overlayActive) - this.close(); - }; - _handleWindowResize = () => { - if (this.overlayActive) - this.close(); - }; - _handleWindowEscape = (e) => { - if (Utils.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive) - this.close(); - }; - _makeAncestorsOverflowVisible() { - this._changedAncestorList = []; - let ancestor = this.placeholder.parentNode; - while (ancestor !== null && ancestor !== document) { - const curr = ancestor; - if (curr.style.overflow !== 'visible') { - curr.style.overflow = 'visible'; - this._changedAncestorList.push(curr); - } - ancestor = ancestor.parentNode; - } - } - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.scrollY - docElem.clientTop, - left: box.left + window.scrollX - docElem.clientLeft - }; - } - _updateVars() { - this.windowWidth = window.innerWidth; - this.windowHeight = window.innerHeight; - this.caption = this.el.getAttribute('data-caption') || ''; - } - // Image - _animateImageIn() { - this.el.style.maxHeight = this.newHeight.toString() + 'px'; - this.el.style.maxWidth = this.newWidth.toString() + 'px'; - const duration = this.options.inDuration; - // from - this.el.style.transition = 'none'; - this.el.style.height = this.originalHeight + 'px'; - this.el.style.width = this.originalWidth + 'px'; - setTimeout(() => { - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.newHeight + 'px'; - this.el.style.width = this.newWidth + 'px'; - this.el.style.left = - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2 + - 'px'; - this.el.style.top = - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2 + - 'px'; - }, 1); - setTimeout(() => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') - this.options.onOpenEnd.call(this, this.el); - }, duration); - /* - anim({ - targets: this.el, // image - height: [this.originalHeight, this.newHeight], - width: [this.originalWidth, this.newWidth], - left: - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2, - top: - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2, - - duration: this.options.inDuration, - easing: 'easeOutQuad', - complete: () => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el); - } - }); - */ - } - _animateImageOut() { - const duration = this.options.outDuration; - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.originalWidth + 'px'; - this.el.style.width = this.originalWidth + 'px'; - this.el.style.left = '0'; - this.el.style.top = '0'; - setTimeout(() => { - this.placeholder.style.height = ''; - this.placeholder.style.width = ''; - this.placeholder.style.position = ''; - this.placeholder.style.top = ''; - this.placeholder.style.left = ''; - // Revert to width or height attribute - if (this.attrWidth) - this.el.setAttribute('width', this.attrWidth.toString()); - if (this.attrHeight) - this.el.setAttribute('height', this.attrHeight.toString()); - this.el.removeAttribute('style'); - if (this.originInlineStyles) - this.el.setAttribute('style', this.originInlineStyles); - // Remove class - this.el.classList.remove('active'); - this.doneAnimating = true; - // Remove overflow overrides on ancestors - this._changedAncestorList.forEach((anchestor) => (anchestor.style.overflow = '')); - // onCloseEnd callback - if (typeof this.options.onCloseEnd === 'function') - this.options.onCloseEnd.call(this, this.el); - }, duration); - } - // Caption - _addCaption() { - this._photoCaption = document.createElement('div'); - this._photoCaption.classList.add('materialbox-caption'); - this._photoCaption.innerText = this.caption; - document.body.append(this._photoCaption); - this._photoCaption.style.display = 'inline'; - // Animate - this._photoCaption.style.transition = 'none'; - this._photoCaption.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '1'; - }, 1); - } - _removeCaption() { - const duration = this.options.outDuration; - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '0'; - setTimeout(() => { - this._photoCaption.remove(); - }, duration); - } - // Overlay - _addOverlay() { - this._overlay = document.createElement('div'); - this._overlay.id = 'materialbox-overlay'; - this._overlay.addEventListener('click', () => { - if (this.doneAnimating) - this.close(); - }, { once: true }); - // Put before in origin image to preserve z-index layering. - this.el.before(this._overlay); - // Set dimensions if needed - const overlayOffset = this._overlay.getBoundingClientRect(); - this._overlay.style.width = this.windowWidth + 'px'; - this._overlay.style.height = this.windowHeight + 'px'; - this._overlay.style.left = -1 * overlayOffset.left + 'px'; - this._overlay.style.top = -1 * overlayOffset.top + 'px'; - // Animate - this._overlay.style.transition = 'none'; - this._overlay.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '1'; - }, 1); - } - _removeOverlay() { - const duration = this.options.outDuration; - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '0'; - setTimeout(() => { - this.overlayActive = false; - this._overlay.remove(); - }, duration); - } - /** - * Open materialbox. - */ - open = () => { - this._updateVars(); - this.originalWidth = this.el.getBoundingClientRect().width; - this.originalHeight = this.el.getBoundingClientRect().height; - // Set states - this.doneAnimating = false; - this.el.classList.add('active'); - this.overlayActive = true; - // onOpenStart callback - if (typeof this.options.onOpenStart === 'function') - this.options.onOpenStart.call(this, this.el); - // Set positioning for placeholder - this.placeholder.style.width = this.placeholder.getBoundingClientRect().width + 'px'; - this.placeholder.style.height = this.placeholder.getBoundingClientRect().height + 'px'; - this.placeholder.style.position = 'relative'; - this.placeholder.style.top = '0'; - this.placeholder.style.left = '0'; - this._makeAncestorsOverflowVisible(); - // Set css on origin - this.el.style.position = 'absolute'; - this.el.style.zIndex = '1000'; - this.el.style.willChange = 'left, top, width, height'; - // Change from width or height attribute to css - this.attrWidth = this.el.getAttribute('width'); - this.attrHeight = this.el.getAttribute('height'); - if (this.attrWidth) { - this.el.style.width = this.attrWidth + 'px'; - this.el.removeAttribute('width'); - } - if (this.attrHeight) { - this.el.style.width = this.attrHeight + 'px'; - this.el.removeAttribute('height'); - } - this._addOverlay(); - // Add and animate caption if it exists - if (this.caption !== '') - this._addCaption(); - // Resize Image - const widthPercent = this.originalWidth / this.windowWidth; - const heightPercent = this.originalHeight / this.windowHeight; - this.newWidth = 0; - this.newHeight = 0; - if (widthPercent > heightPercent) { - // Width first - const ratio = this.originalHeight / this.originalWidth; - this.newWidth = this.windowWidth * 0.9; - this.newHeight = this.windowWidth * 0.9 * ratio; - } - else { - // Height first - const ratio = this.originalWidth / this.originalHeight; - this.newWidth = this.windowHeight * 0.9 * ratio; - this.newHeight = this.windowHeight * 0.9; - } - this._animateImageIn(); - // Handle Exit triggers - window.addEventListener('scroll', this._handleWindowScroll); - window.addEventListener('resize', this._handleWindowResize); - window.addEventListener('keyup', this._handleWindowEscape); - }; - /** - * Close materialbox. - */ - close = () => { - this._updateVars(); - this.doneAnimating = false; - // onCloseStart callback - if (typeof this.options.onCloseStart === 'function') - this.options.onCloseStart.call(this, this.el); - //anim.remove(this.el); - //anim.remove(this._overlay); - //if (this.caption !== '') anim.remove(this._photoCaption); - // disable exit handlers - window.removeEventListener('scroll', this._handleWindowScroll); - window.removeEventListener('resize', this._handleWindowResize); - window.removeEventListener('keyup', this._handleWindowEscape); - this._removeOverlay(); - this._animateImageOut(); - if (this.caption !== '') - this._removeCaption(); - }; -} - -const _defaults$c = { - opacity: 0.5, - inDuration: 250, - outDuration: 250, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - preventScrolling: true, - dismissible: true, - startingTop: '4%', - endingTop: '10%' -}; -class Modal extends Component { - constructor(el, options) { - super(el, options, Modal); - this.el['M_Modal'] = this; - this.options = { - ...Modal.defaults, - ...options - }; - this.el.tabIndex = 0; - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$c; - } - static init(els, options = {}) { - return super.init(els, options, Modal); - } - static getInstance(el) { - return el['M_Modal']; - } - destroy() { } - _setupEventHandlers() { } - _removeEventHandlers() { } - _handleTriggerClick() { } - _handleOverlayClick() { } - _handleModalCloseClick() { } - _handleKeydown() { } - _handleFocus() { } - open() { - return this; - } - close() { - return this; - } - // Experimental! - static #createHtml(config) { - return ` - ${config.header ? '' : ''} - - ${config.header ? '' : ''} - `; - } - static #createHtmlElement(config) { - const dialog = document.createElement('dialog'); - dialog.id = config.id; - return dialog; - } - static create(config) { - return this.#createHtmlElement(config); - } - static { } -} - -const _defaults$b = { - edge: 'left', - draggable: true, - dragTargetWidth: '10px', - inDuration: 250, - outDuration: 200, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - preventScrolling: true -}; -class Sidenav extends Component { - id; - /** Describes open/close state of Sidenav. */ - isOpen; - /** Describes if sidenav is fixed. */ - isFixed; - /** Describes if Sidenav is being dragged. */ - isDragged; - lastWindowWidth; - lastWindowHeight; - static _sidenavs; - _overlay; - dragTarget; - _startingXpos; - _xPos; - _time; - _width; - _initialScrollTop; - _verticallyScrolling; - deltaX; - velocityX; - percentOpen; - constructor(el, options) { - super(el, options, Sidenav); - this.el['M_Sidenav'] = this; - this.options = { - ...Sidenav.defaults, - ...options - }; - this.id = this.el.id; - this.isOpen = false; - this.isFixed = this.el.classList.contains('sidenav-fixed'); - this.isDragged = false; - // Window size variables for window resize checks - this.lastWindowWidth = window.innerWidth; - this.lastWindowHeight = window.innerHeight; - this._createOverlay(); - this._createDragTarget(); - this._setupEventHandlers(); - this._setupClasses(); - this._setupFixed(); - Sidenav._sidenavs.push(this); - } - static get defaults() { - return _defaults$b; - } - /** - * Initializes instances of Sidenav. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Sidenav); - } - static getInstance(el) { - return el['M_Sidenav']; - } - destroy() { - this._removeEventHandlers(); - this._enableBodyScrolling(); - this._overlay.parentNode.removeChild(this._overlay); - this.dragTarget.parentNode.removeChild(this.dragTarget); - this.el['M_Sidenav'] = undefined; - this.el.style.transform = ''; - const index = Sidenav._sidenavs.indexOf(this); - if (index >= 0) { - Sidenav._sidenavs.splice(index, 1); - } - } - _createOverlay() { - this._overlay = document.createElement('div'); - this._overlay.classList.add('sidenav-overlay'); - this._overlay.addEventListener('click', this.close); - document.body.appendChild(this._overlay); - } - _setupEventHandlers() { - if (Sidenav._sidenavs.length === 0) { - document.body.addEventListener('click', this._handleTriggerClick); - } - const passiveIfSupported = null; - this.dragTarget.addEventListener('touchmove', this._handleDragTargetDrag, passiveIfSupported); - this.dragTarget.addEventListener('touchend', this._handleDragTargetRelease); - this._overlay.addEventListener('touchmove', this._handleCloseDrag, passiveIfSupported); - this._overlay.addEventListener('touchend', this._handleCloseRelease); - this.el.addEventListener('touchmove', this._handleCloseDrag); // , passiveIfSupported); - this.el.addEventListener('touchend', this._handleCloseRelease); - this.el.addEventListener('click', this._handleCloseTriggerClick); - // Add resize for side nav fixed - if (this.isFixed) { - window.addEventListener('resize', this._handleWindowResize); - } - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - _removeEventHandlers() { - if (Sidenav._sidenavs.length === 1) { - document.body.removeEventListener('click', this._handleTriggerClick); - } - this.dragTarget.removeEventListener('touchmove', this._handleDragTargetDrag); - this.dragTarget.removeEventListener('touchend', this._handleDragTargetRelease); - this._overlay.removeEventListener('touchmove', this._handleCloseDrag); - this._overlay.removeEventListener('touchend', this._handleCloseRelease); - this.el.removeEventListener('touchmove', this._handleCloseDrag); - this.el.removeEventListener('touchend', this._handleCloseRelease); - this.el.removeEventListener('click', this._handleCloseTriggerClick); - // Remove resize for side nav fixed - if (this.isFixed) { - window.removeEventListener('resize', this._handleWindowResize); - } - } - _handleTriggerClick(e) { - const trigger = e.target.closest('.sidenav-trigger'); - if (e.target && trigger) { - const sidenavId = Utils.getIdFromTrigger(trigger); - const sidenavInstance = document.getElementById(sidenavId)['M_Sidenav']; - if (sidenavInstance) { - sidenavInstance.open(); - } - e.preventDefault(); - } - } - // Set variables needed at the beginning of drag and stop any current transition. - _startDrag(e) { - const clientX = e.targetTouches[0].clientX; - this.isDragged = true; - this._startingXpos = clientX; - this._xPos = this._startingXpos; - this._time = Date.now(); - this._width = this.el.getBoundingClientRect().width; - this._overlay.style.display = 'block'; - this._initialScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop(); - this._verticallyScrolling = false; - } - //Set variables needed at each drag move update tick - _dragMoveUpdate(e) { - const clientX = e.targetTouches[0].clientX; - const currentScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop(); - this.deltaX = Math.abs(this._xPos - clientX); - this._xPos = clientX; - this.velocityX = this.deltaX / (Date.now() - this._time); - this._time = Date.now(); - if (this._initialScrollTop !== currentScrollTop) { - this._verticallyScrolling = true; - } - } - _handleDragTargetDrag = (e) => { - // Check if draggable - if (!this._isDraggable()) - return; - let totalDeltaX = this._calculateDelta(e); - const dragDirection = totalDeltaX > 0 ? 'right' : 'left'; - // Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction - totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX)); - if (this.options.edge === dragDirection) { - totalDeltaX = 0; - } - /** - * transformX is the drag displacement - * transformPrefix is the initial transform placement - * Invert values if Sidenav is right edge - */ - let transformX = totalDeltaX; - let transformPrefix = 'translateX(-100%)'; - if (this.options.edge === 'right') { - transformPrefix = 'translateX(100%)'; - transformX = -transformX; - } - // Calculate open/close percentage of sidenav, with open = 1 and close = 0 - this.percentOpen = Math.min(1, totalDeltaX / this._width); - // Set transform and opacity styles - this.el.style.transform = `${transformPrefix} translateX(${transformX}px)`; - this._overlay.style.opacity = this.percentOpen.toString(); - }; - _handleDragTargetRelease = () => { - if (this.isDragged) { - if (this.percentOpen > 0.2) { - this.open(); - } - else { - this._animateOut(); - } - this.isDragged = false; - this._verticallyScrolling = false; - } - }; - _handleCloseDrag = (e) => { - // Check if open and draggable - if (!this.isOpen || !this._isDraggable()) - return; - let totalDeltaX = this._calculateDelta(e); - // dragDirection is the attempted user drag direction - const dragDirection = totalDeltaX > 0 ? 'right' : 'left'; - totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX)); - if (this.options.edge !== dragDirection) { - totalDeltaX = 0; - } - let transformX = -totalDeltaX; - if (this.options.edge === 'right') { - transformX = -transformX; - } - // Calculate open/close percentage of sidenav, with open = 1 and close = 0 - this.percentOpen = Math.min(1, 1 - totalDeltaX / this._width); - // Set transform and opacity styles - this.el.style.transform = `translateX(${transformX}px)`; - this._overlay.style.opacity = this.percentOpen.toString(); - }; - _calculateDelta = (e) => { - // If not being dragged, set initial drag start variables - if (!this.isDragged) { - this._startDrag(e); - } - // Run touchmove updates - this._dragMoveUpdate(e); - // Calculate raw deltaX - return this._xPos - this._startingXpos; - }; - _handleCloseRelease = () => { - if (this.isOpen && this.isDragged) { - if (this.percentOpen > 0.8) { - this._animateIn(); - } - else { - this.close(); - } - this.isDragged = false; - this._verticallyScrolling = false; - } - }; - // Handles closing of Sidenav when element with class .sidenav-close - _handleCloseTriggerClick = (e) => { - const closeTrigger = e.target.closest('.sidenav-close'); - if (closeTrigger && !this._isCurrentlyFixed()) { - this.close(); - } - }; - _handleWindowResize = () => { - // Only handle horizontal resizes - if (this.lastWindowWidth !== window.innerWidth) { - if (window.innerWidth > 992) { - this.open(); - } - else { - this.close(); - } - } - this.lastWindowWidth = window.innerWidth; - this.lastWindowHeight = window.innerHeight; - }; - _setupClasses() { - if (this.options.edge === 'right') { - this.el.classList.add('right-aligned'); - this.dragTarget.classList.add('right-aligned'); - } - } - _removeClasses() { - this.el.classList.remove('right-aligned'); - this.dragTarget.classList.remove('right-aligned'); - } - _setupFixed() { - if (this._isCurrentlyFixed()) - this.open(); - } - _isDraggable() { - return this.options.draggable && !this._isCurrentlyFixed() && !this._verticallyScrolling; - } - _isCurrentlyFixed() { - return this.isFixed && window.innerWidth > 992; - } - _createDragTarget() { - const dragTarget = document.createElement('div'); - dragTarget.classList.add('drag-target'); - dragTarget.style.width = this.options.dragTargetWidth; - document.body.appendChild(dragTarget); - this.dragTarget = dragTarget; - } - _preventBodyScrolling() { - document.body.style.overflow = 'hidden'; - } - _enableBodyScrolling() { - document.body.style.overflow = ''; - } - /** - * Opens Sidenav. - */ - open = () => { - if (this.isOpen === true) - return; - this.isOpen = true; - // Run onOpenStart callback - if (typeof this.options.onOpenStart === 'function') { - this.options.onOpenStart.call(this, this.el); - } - // Handle fixed Sidenav - if (this._isCurrentlyFixed()) { - // Show if fixed - this.el.style.transform = 'translateX(0)'; - this._enableBodyScrolling(); - this._overlay.style.display = 'none'; - } - // Handle non-fixed Sidenav - else { - if (this.options.preventScrolling) - this._preventBodyScrolling(); - if (!this.isDragged || this.percentOpen != 1) - this._animateIn(); - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - }; - /** - * Closes Sidenav. - */ - close = () => { - if (this.isOpen === false) - return; - this.isOpen = false; - // Run onCloseStart callback - if (typeof this.options.onCloseStart === 'function') { - this.options.onCloseStart.call(this, this.el); - } - // Handle fixed Sidenav - if (this._isCurrentlyFixed()) { - const transformX = this.options.edge === 'left' ? '-105%' : '105%'; - this.el.style.transform = `translateX(${transformX})`; - } - // Handle non-fixed Sidenav - else { - this._enableBodyScrolling(); - if (!this.isDragged || this.percentOpen != 0) { - this._animateOut(); - } - else { - this._overlay.style.display = 'none'; - } - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - }; - _animateIn() { - this._animateSidenavIn(); - this._animateOverlayIn(); - } - _animateOut() { - this._animateSidenavOut(); - this._animateOverlayOut(); - } - _animateSidenavIn() { - let slideOutPercent = this.options.edge === 'left' ? -1 : 1; - if (this.isDragged) { - slideOutPercent = - this.options.edge === 'left' - ? slideOutPercent + this.percentOpen - : slideOutPercent - this.percentOpen; - } - const duration = this.options.inDuration; - // from - this.el.style.transition = 'none'; - this.el.style.transform = 'translateX(' + slideOutPercent * 100 + '%)'; - setTimeout(() => { - this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad - // to - this.el.style.transform = 'translateX(0)'; - }, 1); - setTimeout(() => { - if (typeof this.options.onOpenEnd === 'function') - this.options.onOpenEnd.call(this, this.el); - }, duration); - } - _animateSidenavOut() { - const endPercent = this.options.edge === 'left' ? -1 : 1; - // let slideOutPercent = 0; - // if (this.isDragged) { - // // @todo unused variable - // slideOutPercent = - // this.options.edge === 'left' - // ? endPercent + this.percentOpen - // : endPercent - this.percentOpen; - // } - const duration = this.options.outDuration; - this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad - // to - this.el.style.transform = 'translateX(' + endPercent * 100 + '%)'; - setTimeout(() => { - if (typeof this.options.onCloseEnd === 'function') - this.options.onCloseEnd.call(this, this.el); - }, duration); - } - _animateOverlayIn() { - let start = 0; - if (this.isDragged) - start = this.percentOpen; - else - this._overlay.style.display = 'block'; - // Animation - const duration = this.options.inDuration; - // from - this._overlay.style.transition = 'none'; - this._overlay.style.opacity = start.toString(); - // easeOutQuad - setTimeout(() => { - this._overlay.style.transition = `opacity ${duration}ms ease`; - // to - this._overlay.style.opacity = '1'; - }, 1); - } - _animateOverlayOut() { - const duration = this.options.outDuration; - // easeOutQuad - this._overlay.style.transition = `opacity ${duration}ms ease`; - // to - this._overlay.style.opacity = '0'; - setTimeout(() => { - this._overlay.style.display = 'none'; - }, duration); - } - _setAriaHidden = () => { - this.el.ariaHidden = this.isOpen ? 'false' : 'true'; - const navWrapper = document.querySelector('.nav-wrapper ul'); - if (navWrapper) - navWrapper.ariaHidden = this.isOpen.toString(); - }; - _setTabIndex = () => { - const navLinks = document.querySelectorAll('.nav-wrapper ul li a'); - const sideNavLinks = document.querySelectorAll('.sidenav li a'); - if (navLinks) - navLinks.forEach((navLink) => { - navLink.tabIndex = this.isOpen ? -1 : 0; - }); - if (sideNavLinks) - sideNavLinks.forEach((sideNavLink) => { - sideNavLink.tabIndex = this.isOpen ? 0 : -1; - }); - }; - static { - Sidenav._sidenavs = []; - } -} - -const _defaults$a = { - indicators: true, - height: 400, - duration: 500, - interval: 6000, - pauseOnFocus: true, - pauseOnHover: true, - indicatorLabelFunc: null // Function which will generate a label for the indicators (ARIA) -}; -class Slider extends Component { - /** Index of current slide. */ - activeIndex; - interval; - eventPause; - _slider; - _slides; - _activeSlide; - _indicators; - _hovered; - _focused; - _focusCurrent; - _sliderId; - constructor(el, options) { - super(el, options, Slider); - this.el['M_Slider'] = this; - this.options = { - ...Slider.defaults, - ...options - }; - // init props - this.interval = null; - this.eventPause = false; - this._hovered = false; - this._focused = false; - this._focusCurrent = false; - // setup - this._slider = this.el.querySelector('.slides'); - this._slides = Array.from(this._slider.querySelectorAll('li')); - this.activeIndex = this._slides.findIndex((li) => li.classList.contains('active')); - if (this.activeIndex !== -1) { - this._activeSlide = this._slides[this.activeIndex]; - } - this._setSliderHeight(); - // Sets element id if it does not have one - if (this._slider.hasAttribute('id')) - this._sliderId = this._slider.getAttribute('id'); - else { - this._sliderId = 'slider-' + Utils.guid(); - this._slider.setAttribute('id', this._sliderId); - } - const placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; - // Set initial positions of captions - this._slides.forEach((slide) => { - // Caption - //const caption = slide.querySelector('.caption'); - //if (caption) this._animateCaptionIn(caption, 0); - // Set Images as Background Images - const img = slide.querySelector('img'); - if (img) { - if (img.src !== placeholderBase64) { - img.style.backgroundImage = 'url(' + img.src + ')'; - img.src = placeholderBase64; - } - } - // Sets slide as focusable by code - if (!slide.hasAttribute('tabindex')) - slide.setAttribute('tabindex', '-1'); - // Removes initial visibility from "inactive" slides - slide.style.visibility = 'hidden'; - }); - this._setupIndicators(); - // Show active slide - if (this._activeSlide) { - this._activeSlide.style.display = 'block'; - this._activeSlide.style.visibility = 'visible'; - } - else { - this.activeIndex = 0; - this._slides[0].classList.add('active'); - this._slides[0].style.visibility = 'visible'; - this._activeSlide = this._slides[0]; - this._animateSlide(this._slides[0], true); - // Update indicators - if (this.options.indicators) { - this._indicators[this.activeIndex].children[0].classList.add('active'); - } - } - this._setupEventHandlers(); - // auto scroll - this.start(); - } - static get defaults() { - return _defaults$a; - } - /** - * Initializes instances of Slider. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Slider); - } - static getInstance(el) { - return el['M_Slider']; - } - destroy() { - this.pause(); - this._removeIndicators(); - this._removeEventHandlers(); - this.el['M_Slider'] = undefined; - } - _setupEventHandlers() { - if (this.options.pauseOnFocus) { - this.el.addEventListener('focusin', this._handleAutoPauseFocus); - this.el.addEventListener('focusout', this._handleAutoStartFocus); - } - if (this.options.pauseOnHover) { - this.el.addEventListener('mouseenter', this._handleAutoPauseHover); - this.el.addEventListener('mouseleave', this._handleAutoStartHover); - } - if (this.options.indicators) { - this._indicators.forEach((el) => { - el.addEventListener('click', this._handleIndicatorClick); - }); - } - } - _removeEventHandlers() { - if (this.options.pauseOnFocus) { - this.el.removeEventListener('focusin', this._handleAutoPauseFocus); - this.el.removeEventListener('focusout', this._handleAutoStartFocus); - } - if (this.options.pauseOnHover) { - this.el.removeEventListener('mouseenter', this._handleAutoPauseHover); - this.el.removeEventListener('mouseleave', this._handleAutoStartHover); - } - if (this.options.indicators) { - this._indicators.forEach((el) => { - el.removeEventListener('click', this._handleIndicatorClick); - }); - } - } - _handleIndicatorClick = (e) => { - const el = e.target.parentElement; - const currIndex = [...el.parentNode.children].indexOf(el); - this._focusCurrent = true; - this.set(currIndex); - }; - _handleAutoPauseHover = () => { - this._hovered = true; - if (this.interval != null) { - this._pause(true); - } - }; - _handleAutoPauseFocus = () => { - this._focused = true; - if (this.interval != null) { - this._pause(true); - } - }; - _handleAutoStartHover = () => { - this._hovered = false; - if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) { - this.start(); - } - }; - _handleAutoStartFocus = () => { - this._focused = false; - if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) { - this.start(); - } - }; - _handleInterval = () => { - const activeElem = this._slider.querySelector('.active'); - let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem); - if (this._slides.length === newActiveIndex + 1) - newActiveIndex = 0; // loop to start - else - newActiveIndex += 1; - this.set(newActiveIndex); - }; - _animateSlide(slide, isDirectionIn) { - let dx = 0, dy = 0; - // from - slide.style.opacity = isDirectionIn ? '0' : '1'; - setTimeout(() => { - slide.style.transition = `opacity ${this.options.duration}ms ease`; - // to - slide.style.opacity = isDirectionIn ? '1' : '0'; - }, 1); - // Caption - const caption = slide.querySelector('.caption'); - if (!caption) - return; - if (caption.classList.contains('center-align')) - dy = -100; - else if (caption.classList.contains('right-align')) - dx = 100; - else if (caption.classList.contains('left-align')) - dx = -100; - // from - caption.style.opacity = isDirectionIn ? '0' : '1'; - caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`; - setTimeout(() => { - caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`; - // to - caption.style.opacity = isDirectionIn ? '1' : '0'; - caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`; - }, this.options.duration); // delay - } - _setSliderHeight() { - // If fullscreen, do nothing - if (!this.el.classList.contains('fullscreen')) { - if (this.options.indicators) { - // Add height if indicators are present - this.el.style.height = this.options.height + 40 + 'px'; //.css('height', this.options.height + 40 + 'px'); - } - else { - this.el.style.height = this.options.height + 'px'; - } - this._slider.style.height = this.options.height + 'px'; - } - } - _setupIndicators() { - if (this.options.indicators) { - const ul = document.createElement('ul'); - ul.classList.add('indicators'); - const arrLi = []; - this._slides.forEach((el, i) => { - const label = this.options.indicatorLabelFunc - ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0) - : `${i + 1}`; - const li = document.createElement('li'); - li.classList.add('indicator-item'); - li.innerHTML = ``; - arrLi.push(li); - ul.append(li); - }); - this.el.append(ul); - this._indicators = arrLi; - } - } - _removeIndicators() { - this.el.querySelector('ul.indicators').remove(); //find('ul.indicators').remove(); - } - set(index) { - // Wrap around indices. - if (index >= this._slides.length) - index = 0; - else if (index < 0) - index = this._slides.length - 1; - // Only do if index changes - if (this.activeIndex === index) - return; - this._activeSlide = this._slides[this.activeIndex]; - const _caption = this._activeSlide.querySelector('.caption'); - this._activeSlide.classList.remove('active'); - // Enables every slide - this._slides.forEach((slide) => (slide.style.visibility = 'visible')); - //--- Hide active Slide + Caption - this._activeSlide.style.opacity = '0'; - setTimeout(() => { - this._slides.forEach((slide) => { - if (slide.classList.contains('active')) - return; - slide.style.opacity = '0'; - slide.style.transform = 'translate(0, 0)'; - // Disables invisible slides (for assistive technologies) - slide.style.visibility = 'hidden'; - }); - }, this.options.duration); - // Hide active Caption - //this._animateCaptionIn(_caption, this.options.duration); - _caption.style.opacity = '0'; - // Update indicators - if (this.options.indicators) { - const activeIndicator = this._indicators[this.activeIndex].children[0]; - const nextIndicator = this._indicators[index].children[0]; - activeIndicator.classList.remove('active'); - nextIndicator.classList.add('active'); - if (typeof this.options.indicatorLabelFunc === 'function') { - activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, this.activeIndex, false); - nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true); - } - } - //--- Show new Slide + Caption - this._animateSlide(this._slides[index], true); - this._slides[index].classList.add('active'); - this.activeIndex = index; - // Reset interval, if allowed. This check prevents autostart - // when slider is paused, since it can be changed though indicators. - if (this.interval != null) { - this.start(); - } - } - _pause(fromEvent) { - clearInterval(this.interval); - this.eventPause = fromEvent; - this.interval = null; - } - /** - * Pause slider autoslide. - */ - pause = () => { - this._pause(false); - }; - /** - * Start slider autoslide. - */ - start = () => { - clearInterval(this.interval); - this.interval = setInterval(this._handleInterval, this.options.duration + this.options.interval); - this.eventPause = false; - }; - /** - * Move to next slider. - */ - next = () => { - let newIndex = this.activeIndex + 1; - // Wrap around indices. - if (newIndex >= this._slides.length) - newIndex = 0; - else if (newIndex < 0) - newIndex = this._slides.length - 1; - this.set(newIndex); - }; - /** - * Move to prev slider. - */ - prev = () => { - let newIndex = this.activeIndex - 1; - // Wrap around indices. - if (newIndex >= this._slides.length) - newIndex = 0; - else if (newIndex < 0) - newIndex = this._slides.length - 1; - this.set(newIndex); - }; -} - -const _defaults$9 = { - duration: 300, - onShow: null, - swipeable: false, - responsiveThreshold: Infinity // breakpoint for swipeable -}; -class Tabs extends Component { - _tabLinks; - _index; - _indicator; - _tabWidth; - _tabsWidth; - _tabsCarousel; - _activeTabLink; - _content; - constructor(el, options) { - super(el, options, Tabs); - this.el['M_Tabs'] = this; - this.options = { - ...Tabs.defaults, - ...options - }; - this._tabLinks = this.el.querySelectorAll('li.tab > a'); - this._index = 0; - this._setupActiveTabLink(); - if (this.options.swipeable) { - this._setupSwipeableTabs(); - } - else { - this._setupNormalTabs(); - } - // Setup tabs indicator after content to ensure accurate widths - this._setTabsAndTabWidth(); - this._createIndicator(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$9; - } - /** - * Initializes instances of Tabs. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Tabs); - } - static getInstance(el) { - return el['M_Tabs']; - } - destroy() { - this._removeEventHandlers(); - this._indicator.parentNode.removeChild(this._indicator); - if (this.options.swipeable) { - this._teardownSwipeableTabs(); - } - else { - this._teardownNormalTabs(); - } - this.el['M_Tabs'] = undefined; - } - /** - * The index of tab that is currently shown. - */ - get index() { - return this._index; - } - _setupEventHandlers() { - window.addEventListener('resize', this._handleWindowResize); - this.el.addEventListener('click', this._handleTabClick); - // map vertical scrolling to horizontal scrolling because no scrollbar is shown on desktop - this.el.addEventListener('wheel', (event) => { - if (event.deltaY !== 0) { - event.preventDefault(); - this.el.scrollLeft += event.deltaY * 1; - } - }); - } - _removeEventHandlers() { - window.removeEventListener('resize', this._handleWindowResize); - this.el.removeEventListener('click', this._handleTabClick); - } - _handleWindowResize = () => { - this._setTabsAndTabWidth(); - if (this._tabWidth !== 0 && this._tabsWidth !== 0) { - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - }; - _handleTabClick = (e) => { - let tabLink = e.target; - if (!tabLink) - return; - let tab = tabLink.parentElement; - while (tab && !tab.classList.contains('tab')) { - tabLink = tabLink.parentElement; - tab = tab.parentElement; - } - // Handle click on tab link only - if (!tabLink || !tab.classList.contains('tab')) - return; - // is disabled? - if (tab.classList.contains('disabled')) { - e.preventDefault(); - return; - } - // Act as regular link if target attribute is specified. - if (tabLink.hasAttribute('target')) - return; - // Make the old tab inactive. - this._activeTabLink.classList.remove('active'); - const _oldContent = this._content; - // Update the variables with the new link and content - this._activeTabLink = tabLink; - if (tabLink.hash) - this._content = document.querySelector(tabLink.hash); - this._tabLinks = this.el.querySelectorAll('li.tab > a'); - // Make the tab active - this._activeTabLink.classList.add('active'); - const prevIndex = this._index; - this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0); - // Swap content - if (this.options.swipeable) { - if (this._tabsCarousel) { - this._tabsCarousel.set(this._index, () => { - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - }); - } - } - else { - if (this._content) { - this._content.style.display = 'block'; - this._content.classList.add('active'); - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - if (_oldContent && _oldContent !== this._content) { - _oldContent.style.display = 'none'; - _oldContent.classList.remove('active'); - } - } - } - // Update widths after content is swapped (scrollbar bugfix) - this._setTabsAndTabWidth(); - this._animateIndicator(prevIndex); - e.preventDefault(); - }; - _createIndicator() { - const indicator = document.createElement('li'); - indicator.classList.add('indicator'); - this.el.appendChild(indicator); - this._indicator = indicator; - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - _setupActiveTabLink() { - // If the location.hash matches one of the links, use that as the active tab. - this._activeTabLink = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === location.hash); - // If no match is found, use the first link or any with class 'active' as the initial active tab. - if (!this._activeTabLink) { - let activeTabLink = this.el.querySelector('li.tab a.active'); - if (!activeTabLink) { - activeTabLink = this.el.querySelector('li.tab a'); - } - this._activeTabLink = activeTabLink; - } - Array.from(this._tabLinks).forEach((a) => a.classList.remove('active')); - this._activeTabLink.classList.add('active'); - this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0); - if (this._activeTabLink && this._activeTabLink.hash) { - this._content = document.querySelector(this._activeTabLink.hash); - if (this._content) - this._content.classList.add('active'); - } - } - _setupSwipeableTabs() { - // Change swipeable according to responsive threshold - if (window.innerWidth > this.options.responsiveThreshold) - this.options.swipeable = false; - const tabsContent = []; - this._tabLinks.forEach((a) => { - if (a.hash) { - const currContent = document.querySelector(a.hash); - currContent.classList.add('carousel-item'); - tabsContent.push(currContent); - } - }); - // Create Carousel-Wrapper around Tab-Contents - const tabsWrapper = document.createElement('div'); - tabsWrapper.classList.add('tabs-content', 'carousel', 'carousel-slider'); - // Wrap around - tabsContent[0].parentElement.insertBefore(tabsWrapper, tabsContent[0]); - tabsContent.forEach((tabContent) => { - tabsWrapper.appendChild(tabContent); - tabContent.style.display = ''; - }); - // Keep active tab index to set initial carousel slide - const tab = this._activeTabLink.parentElement; - const activeTabIndex = Array.from(tab.parentNode.children).indexOf(tab); - this._tabsCarousel = Carousel.init(tabsWrapper, { - fullWidth: true, - noWrap: true, - onCycleTo: (item) => { - const prevIndex = this._index; - this._index = Array.from(item.parentNode.children).indexOf(item); - this._activeTabLink.classList.remove('active'); - this._activeTabLink = Array.from(this._tabLinks)[this._index]; - this._activeTabLink.classList.add('active'); - this._animateIndicator(prevIndex); - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - } - }); - // Set initial carousel slide to active tab - this._tabsCarousel.set(activeTabIndex); - } - _teardownSwipeableTabs() { - const tabsWrapper = this._tabsCarousel.el; - this._tabsCarousel.destroy(); - // Unwrap - tabsWrapper.append(tabsWrapper.parentElement); - tabsWrapper.remove(); - } - _setupNormalTabs() { - // Hide Tabs Content - Array.from(this._tabLinks).forEach((a) => { - if (a === this._activeTabLink) - return; - if (a.hash) { - const currContent = document.querySelector(a.hash); - if (currContent) - currContent.style.display = 'none'; - } - }); - } - _teardownNormalTabs() { - // show Tabs Content - this._tabLinks.forEach((a) => { - if (a.hash) { - const currContent = document.querySelector(a.hash); - if (currContent) - currContent.style.display = ''; - } - }); - } - _setTabsAndTabWidth() { - this._tabsWidth = this.el.getBoundingClientRect().width; - this._tabWidth = Math.max(this._tabsWidth, this.el.scrollWidth) / this._tabLinks.length; - } - _calcRightPos(el) { - return Math.ceil(this._tabsWidth - el.offsetLeft - el.getBoundingClientRect().width); - } - _calcLeftPos(el) { - return Math.floor(el.offsetLeft); - } - /** - * Recalculate tab indicator position. This is useful when - * the indicator position is not correct. - */ - updateTabIndicator() { - this._setTabsAndTabWidth(); - this._animateIndicator(this._index); - } - _animateIndicator(prevIndex) { - let leftDelay = 0, rightDelay = 0; - const isMovingLeftOrStaying = this._index - prevIndex >= 0; - if (isMovingLeftOrStaying) - leftDelay = 90; - else - rightDelay = 90; - // in v1: easeOutQuad - this._indicator.style.transition = ` - left ${this.options.duration}ms ease-out ${leftDelay}ms, - right ${this.options.duration}ms ease-out ${rightDelay}ms`; - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - /** - * Show tab content that corresponds to the tab with the id. - * @param tabId The id of the tab that you want to switch to. - */ - select(tabId) { - const tab = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === '#' + tabId); - if (tab) - tab.click(); - } -} - -const _defaults$8 = { - dialRadius: 135, - outerRadius: 105, - innerRadius: 70, - tickRadius: 20, - duration: 350, - container: null, - defaultTime: 'now', // default time, 'now' or '13:14' e.g. - fromNow: 0, // Millisecond offset from the defaultTime - showClearBtn: false, - autoSubmit: true, - // internationalization - i18n: { - cancel: 'Cancel', - clear: 'Clear', - done: 'Ok' - }, - twelveHour: true, // change to 12 hour AM/PM clock from 24 hour - vibrate: true, // vibrate the device when dragging clock hand - // Callbacks - onSelect: null, - onInputInteraction: null, - onDone: null, - onCancel: null, - displayPlugin: null, - displayPluginOptions: null -}; -class Timepicker extends Component { - id; - containerEl; - plate; - digitalClock; - inputHours; - inputMinutes; - x0; - y0; - moved; - dx; - dy; - /** - * Current view on the timepicker. - * @default 'hours' - */ - currentView; - hand; - minutesView; - hours; - minutes; - /** The selected time. */ - time; - /** - * If the time is AM or PM on twelve-hour clock. - * @default 'PM' - */ - amOrPm; - static _template; - /** Vibrate device when dragging clock hand. */ - vibrate; - _canvas; - hoursView; - spanAmPm; - footer; - _amBtn; - _pmBtn; - bg; - bearing; - g; - toggleViewTimer; - vibrateTimer; - displayPlugin; - constructor(el, options) { - super(el, options, Timepicker); - this.el['M_Timepicker'] = this; - this.options = { - ...Timepicker.defaults, - ...options - }; - this.id = Utils.guid(); - this._insertHTMLIntoDOM(); - this._setupVariables(); - this._setupEventHandlers(); - this._clockSetup(); - if (this.options.displayPlugin) - this._setupDisplayPlugin(); - this._pickerSetup(); - } - static get defaults() { - return _defaults$8; - } - /** - * Initializes instances of Timepicker. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Timepicker); - } - static _addLeadingZero(num) { - return (num < 10 ? '0' : '') + num; - } - static _createSVGEl(name) { - const svgNS = 'http://www.w3.org/2000/svg'; - return document.createElementNS(svgNS, name); - } - static _Pos(e) { - if (e.type.startsWith('touch') && e.targetTouches.length >= 1) { - return { - x: e.targetTouches[0].clientX, - y: e.targetTouches[0].clientY - }; - } - // mouse event - return { x: e.clientX, y: e.clientY }; - } - static getInstance(el) { - return el['M_Timepicker']; - } - destroy() { - this._removeEventHandlers(); - this.containerEl.remove(); - this.el['M_Timepicker'] = undefined; - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleInputClick); - // @todo allow input field to fill values from input field when container/modal opens - this.el.addEventListener('keydown', this._handleInputKeydown); - this.plate.addEventListener('mousedown', this._handleClockClickStart); - this.plate.addEventListener('touchstart', this._handleClockClickStart); - this.digitalClock.addEventListener('keyup', this._inputFromTextField); - this.inputHours.addEventListener('focus', () => this.showView('hours')); - this.inputHours.addEventListener('focusout', () => this.formatHours()); - this.inputMinutes.addEventListener('focus', () => this.showView('minutes')); - this.inputMinutes.addEventListener('focusout', () => this.formatMinutes()); - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleInputClick); - this.el.removeEventListener('keydown', this._handleInputKeydown); - } - _handleInputClick = () => { - this.inputHours.focus(); - if (typeof this.options.onInputInteraction === 'function') - this.options.onInputInteraction.call(this); - if (this.displayPlugin) - this.displayPlugin.show(); - }; - _handleInputKeydown = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this.inputHours.focus(); - if (typeof this.options.onInputInteraction === 'function') - this.options.onInputInteraction.call(this); - if (this.displayPlugin) - this.displayPlugin.show(); - } - }; - _handleTimeInputEnterKey = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this._inputFromTextField(); - } - }; - _handleClockClickStart = (e) => { - e.preventDefault(); - const clockPlateBR = this.plate.getBoundingClientRect(); - const offset = { x: clockPlateBR.left, y: clockPlateBR.top }; - this.x0 = offset.x + this.options.dialRadius; - this.y0 = offset.y + this.options.dialRadius; - this.moved = false; - const clickPos = Timepicker._Pos(e); - this.dx = clickPos.x - this.x0; - this.dy = clickPos.y - this.y0; - // Set clock hands - this.setHand(this.dx, this.dy, false); - // Mousemove on document - document.addEventListener('mousemove', this._handleDocumentClickMove); - document.addEventListener('touchmove', this._handleDocumentClickMove); - // Mouseup on document - document.addEventListener('mouseup', this._handleDocumentClickEnd); - document.addEventListener('touchend', this._handleDocumentClickEnd); - }; - _handleDocumentClickMove = (e) => { - e.preventDefault(); - const clickPos = Timepicker._Pos(e); - const x = clickPos.x - this.x0; - const y = clickPos.y - this.y0; - this.moved = true; - this.setHand(x, y, false); - }; - _handleDocumentClickEnd = (e) => { - e.preventDefault(); - document.removeEventListener('mouseup', this._handleDocumentClickEnd); - document.removeEventListener('touchend', this._handleDocumentClickEnd); - const clickPos = Timepicker._Pos(e); - const x = clickPos.x - this.x0; - const y = clickPos.y - this.y0; - if (this.moved && x === this.dx && y === this.dy) { - this.setHand(x, y); - } - if (this.currentView === 'hours') { - this.inputMinutes.focus(); - this.showView('minutes', this.options.duration / 2); - } - else { - // this.minutesView.classList.add('timepicker-dial-out'); - setTimeout(() => { - if (this.options.autoSubmit) - this.done(); - }, this.options.duration / 2); - } - if (typeof this.options.onSelect === 'function') { - this.options.onSelect.call(this, this.hours, this.minutes); - } - // Unbind mousemove event - document.removeEventListener('mousemove', this._handleDocumentClickMove); - document.removeEventListener('touchmove', this._handleDocumentClickMove); - }; - _insertHTMLIntoDOM() { - const template = document.createElement('template'); - template.innerHTML = Timepicker._template.trim(); - this.containerEl = template.content.firstChild; - this.containerEl.id = 'container-' + this.id; - // Append popover to input by default - const optEl = this.options.container; - const containerEl = optEl instanceof HTMLElement ? optEl : document.querySelector(optEl); - if (this.options.container && !!containerEl) { - containerEl.append(this.containerEl); - } - else { - this.el.parentElement.appendChild(this.containerEl); - } - } - _setupVariables() { - this.currentView = 'hours'; - this.vibrate = navigator.vibrate - ? 'vibrate' - : navigator['webkitVibrate'] - ? 'webkitVibrate' - : null; - this._canvas = this.containerEl.querySelector('.timepicker-canvas'); - this.plate = this.containerEl.querySelector('.timepicker-plate'); - this.digitalClock = this.containerEl.querySelector('.timepicker-display-column'); - this.hoursView = this.containerEl.querySelector('.timepicker-hours'); - this.minutesView = this.containerEl.querySelector('.timepicker-minutes'); - this.inputHours = this.containerEl.querySelector('.timepicker-input-hours'); - this.inputMinutes = this.containerEl.querySelector('.timepicker-input-minutes'); - this.spanAmPm = this.containerEl.querySelector('.timepicker-span-am-pm'); - this.footer = this.containerEl.querySelector('.timepicker-footer'); - this.amOrPm = 'PM'; - } - /*private _createButton(text: string, visibility: string): HTMLButtonElement { - const button = document.createElement('button'); - button.classList.add('btn', 'waves-effect', 'text'); - button.style.visibility = visibility; - button.type = 'button'; - button.tabIndex = -1; - button.innerText = text; - return button; - }*/ - _pickerSetup() { - // clearButton.classList.add('timepicker-clear'); - // clearButton.addEventListener('click', this.clear); - // this.footer.appendChild(clearButton); - if (this.options.showClearBtn) { - Utils.createButton(this.footer, this.options.i18n.clear, ['timepicker-clear'], true, this.clear); - } - if (!this.options.autoSubmit) { - /*const confirmationBtnsContainer = document.createElement('div'); - confirmationBtnsContainer.classList.add('confirmation-btns'); - this.footer.append(confirmationBtnsContainer); - - const cancelButton = this._createButton(this.options.i18n.cancel, ''); - cancelButton.classList.add('timepicker-close'); - cancelButton.addEventListener('click', this.close); - confirmationBtnsContainer.appendChild(cancelButton); - - const doneButton = this._createButton(this.options.i18n.done, ''); - doneButton.classList.add('timepicker-close'); - //doneButton.addEventListener('click', this._finishSelection); - confirmationBtnsContainer.appendChild(doneButton);*/ - Utils.createConfirmationContainer(this.footer, this.options.i18n.done, this.options.i18n.cancel, this.confirm, this.cancel); - } - this._updateTimeFromInput(); - this.showView('hours'); - } - _setupDisplayPlugin() { - if (this.options.displayPlugin === 'docked') - this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions); - if (this.options.displayPlugin === 'modal') { - this.displayPlugin = ModalDisplayPlugin.init(this.el, this.containerEl, { - ...this.options.displayPluginOptions, - ...{ classList: ['timepicker-modal'] } - }); - this.footer.remove(); - this.footer = this.displayPlugin.footer; - } - } - _clockSetup() { - if (this.options.twelveHour) { - // AM Button - this._amBtn = document.createElement('div'); - this._amBtn.classList.add('am-btn', 'btn'); - this._amBtn.innerText = 'AM'; - this._amBtn.tabIndex = 0; - this._amBtn.addEventListener('click', this._handleAmPmClick); - this._amBtn.addEventListener('keypress', this._handleAmPmKeypress); - this.spanAmPm.appendChild(this._amBtn); - // PM Button - this._pmBtn = document.createElement('div'); - this._pmBtn.classList.add('pm-btn', 'btn'); - this._pmBtn.innerText = 'PM'; - this._pmBtn.tabIndex = 0; - this._pmBtn.addEventListener('click', this._handleAmPmClick); - this._pmBtn.addEventListener('keypress', this._handleAmPmKeypress); - this.spanAmPm.appendChild(this._pmBtn); - } - this._buildHoursView(); - this._buildMinutesView(); - this._buildSVGClock(); - } - _buildSVGClock() { - // Draw clock hands and others - const dialRadius = this.options.dialRadius; - const tickRadius = this.options.tickRadius; - const diameter = dialRadius * 2; - const svg = Timepicker._createSVGEl('svg'); - svg.setAttribute('class', 'timepicker-svg'); - svg.setAttribute('width', diameter.toString()); - svg.setAttribute('height', diameter.toString()); - const g = Timepicker._createSVGEl('g'); - g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')'); - const bearing = Timepicker._createSVGEl('circle'); - bearing.setAttribute('class', 'timepicker-canvas-bearing'); - bearing.setAttribute('cx', '0'); - bearing.setAttribute('cy', '0'); - bearing.setAttribute('r', '4'); - const hand = Timepicker._createSVGEl('line'); - hand.setAttribute('x1', '0'); - hand.setAttribute('y1', '0'); - const bg = Timepicker._createSVGEl('circle'); - bg.setAttribute('class', 'timepicker-canvas-bg'); - bg.setAttribute('r', tickRadius.toString()); - g.appendChild(hand); - g.appendChild(bg); - g.appendChild(bearing); - svg.appendChild(g); - this._canvas.appendChild(svg); - this.hand = hand; - this.bg = bg; - this.bearing = bearing; - this.g = g; - } - _buildHoursView() { - // const $tick = document.createElement('div'); - // $tick.classList.add('timepicker-tick'); - // Hours view - if (this.options.twelveHour) { - for (let i = 1; i < 13; i += 1) { - // const tick = $tick.cloneNode(true); - const radian = (i / 6) * Math.PI; - const radius = this.options.outerRadius; - this._buildHoursTick(i, radian, radius); - } - } - else { - for (let i = 0; i < 24; i += 1) { - // const tick = $tick.cloneNode(true); - const radian = (i / 6) * Math.PI; - const inner = i > 0 && i < 13; - const radius = inner ? this.options.innerRadius : this.options.outerRadius; - this._buildHoursTick(i, radian, radius); - } - } - } - _buildHoursTick(i, radian, radius) { - const tick = document.createElement('div'); - tick.classList.add('timepicker-tick'); - tick.style.left = - this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px'; - tick.style.top = - this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px'; - tick.innerHTML = i === 0 ? '00' : i.toString(); - this.hoursView.appendChild(tick); - } - _buildMinutesView() { - const _tick = document.createElement('div'); - _tick.classList.add('timepicker-tick'); - // Minutes view - for (let i = 0; i < 60; i += 5) { - const tick = _tick.cloneNode(true); - const radian = (i / 30) * Math.PI; - tick.style.left = - this.options.dialRadius + - Math.sin(radian) * this.options.outerRadius - - this.options.tickRadius + - 'px'; - tick.style.top = - this.options.dialRadius - - Math.cos(radian) * this.options.outerRadius - - this.options.tickRadius + - 'px'; - tick.innerHTML = Timepicker._addLeadingZero(i); - this.minutesView.appendChild(tick); - } - } - _handleAmPmClick = (e) => { - this._handleAmPmInteraction(e.target); - }; - _handleAmPmKeypress = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleAmPmInteraction(e.target); - } - }; - _handleAmPmInteraction = (e) => { - this.amOrPm = e.classList.contains('am-btn') ? 'AM' : 'PM'; - this._updateAmPmView(); - }; - _updateAmPmView() { - if (this.options.twelveHour) { - if (this.amOrPm === 'PM') { - this._amBtn.classList.remove('filled'); - this._pmBtn.classList.add('filled'); - } - else if (this.amOrPm === 'AM') { - this._amBtn.classList.add('filled'); - this._pmBtn.classList.remove('filled'); - } - } - } - _updateTimeFromInput() { - // Get the time - let value = ((this.el.value || this.options.defaultTime || '') + '').split(':'); - if (this.options.twelveHour && !(typeof value[1] === 'undefined')) { - if (value[1].toUpperCase().indexOf('AM') > 0) { - this.amOrPm = 'AM'; - } - else { - this.amOrPm = 'PM'; - } - value[1] = value[1].replace('AM', '').replace('PM', ''); - } - if (value[0] === 'now') { - const now = new Date(+new Date() + this.options.fromNow); - value = [now.getHours().toString(), now.getMinutes().toString()]; - if (this.options.twelveHour) { - this.amOrPm = parseInt(value[0]) >= 12 && parseInt(value[0]) < 24 ? 'PM' : 'AM'; - } - } - this.hours = +value[0] || 0; - this.minutes = +value[1] || 0; - this.inputHours.value = Timepicker._addLeadingZero(this.hours); - this.inputMinutes.value = Timepicker._addLeadingZero(this.minutes); - this._updateAmPmView(); - } - /** - * Show hours or minutes view on timepicker. - * @param view The name of the view you want to switch to, 'hours' or 'minutes'. - * @param delay - */ - showView = (view, delay = null) => { - if (view === 'minutes' && getComputedStyle(this.hoursView).visibility === 'visible') ; - const isHours = view === 'hours', nextView = isHours ? this.hoursView : this.minutesView, hideView = isHours ? this.minutesView : this.hoursView; - this.currentView = view; - /*if (isHours) { - this.inputHours.classList.add('text-primary'); - this.inputMinutes.classList.remove('text-primary'); - } else { - this.inputHours.classList.remove('text-primary'); - this.inputMinutes.classList.add('text-primary'); - }*/ - // Transition view - hideView.classList.add('timepicker-dial-out'); - nextView.style.visibility = 'visible'; - nextView.classList.remove('timepicker-dial-out'); - // Reset clock hand - this.resetClock(delay); - // After transitions ended - clearTimeout(this.toggleViewTimer); - this.toggleViewTimer = setTimeout(() => { - hideView.style.visibility = 'hidden'; - }, this.options.duration); - }; - resetClock(delay) { - const view = this.currentView, value = this[view], isHours = view === 'hours', unit = Math.PI / (isHours ? 6 : 30), radian = value * unit, radius = isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius, x = Math.sin(radian) * radius, y = -Math.cos(radian) * radius; - if (delay) { - this._canvas?.classList.add('timepicker-canvas-out'); - setTimeout(() => { - this._canvas?.classList.remove('timepicker-canvas-out'); - this.setHand(x, y); - }, delay); - } - else { - this.setHand(x, y); - } - } - _inputFromTextField = () => { - const isHours = this.currentView === 'hours'; - if (isHours && this.inputHours.value !== '') { - const value = parseInt(this.inputHours.value); - if (value > 0 && value < (this.options.twelveHour ? 13 : 24)) { - this.hours = value; - } - else { - this.setHoursDefault(); - } - this.drawClockFromTimeInput(this.hours, isHours); - } - else if (!isHours && this.inputMinutes.value !== '') { - const value = parseInt(this.inputMinutes.value); - if (value >= 0 && value < 60) { - this.minutes = value; - } - else { - this.minutes = new Date().getMinutes(); - this.inputMinutes.value = this.minutes.toString(); - } - this.drawClockFromTimeInput(this.minutes, isHours); - } - }; - drawClockFromTimeInput(value, isHours) { - const unit = Math.PI / (isHours ? 6 : 30); - const radian = value * unit; - let radius; - if (this.options.twelveHour) { - radius = this.options.outerRadius; - } - else { - radius = - isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius; - } - this.setClockAttributes(radian, radius); - } - setHand(x, y, roundBy5 = false) { - const isHours = this.currentView === 'hours', unit = Math.PI / (isHours || roundBy5 ? 6 : 30), z = Math.sqrt(x * x + y * y), inner = isHours && z < (this.options.outerRadius + this.options.innerRadius) / 2; - let radian = Math.atan2(x, -y), radius = inner ? this.options.innerRadius : this.options.outerRadius; - if (this.options.twelveHour) { - radius = this.options.outerRadius; - } - // Radian should in range [0, 2PI] - if (radian < 0) { - radian = Math.PI * 2 + radian; - } - // Get the round value - let value = Math.round(radian / unit); - // Get the round radian - radian = value * unit; - // Correct the hours or minutes - if (this.options.twelveHour) { - if (isHours) { - if (value === 0) - value = 12; - } - else { - if (roundBy5) - value *= 5; - if (value === 60) - value = 0; - } - } - else { - if (isHours) { - if (value === 12) { - value = 0; - } - value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12; - } - else { - if (roundBy5) { - value *= 5; - } - if (value === 60) { - value = 0; - } - } - } - // Once hours or minutes changed, vibrate the device - if (this[this.currentView] !== value) { - if (this.vibrate && this.options.vibrate) { - // Do not vibrate too frequently - if (!this.vibrateTimer) { - navigator[this.vibrate](10); - this.vibrateTimer = setTimeout(() => { - this.vibrateTimer = null; - }, 100); - } - } - } - this[this.currentView] = value; - if (isHours) { - this.inputHours.value = Timepicker._addLeadingZero(value); - } - else { - this.inputMinutes.value = Timepicker._addLeadingZero(value); - } - // Set clock hand and others' position - this.setClockAttributes(radian, radius); - } - setClockAttributes(radian, radius) { - const cx1 = Math.sin(radian) * (radius - this.options.tickRadius), cy1 = -Math.cos(radian) * (radius - this.options.tickRadius), cx2 = Math.sin(radian) * radius, cy2 = -Math.cos(radian) * radius; - this.hand.setAttribute('x2', cx1.toString()); - this.hand.setAttribute('y2', cy1.toString()); - this.bg.setAttribute('cx', cx2.toString()); - this.bg.setAttribute('cy', cy2.toString()); - } - formatHours() { - if (this.inputHours.value == '') - this.setHoursDefault(); - this.inputHours.value = Timepicker._addLeadingZero(Number(this.inputHours.value)); - } - formatMinutes() { - if (this.inputMinutes.value == '') - this.minutes = new Date().getMinutes(); - this.inputMinutes.value = Timepicker._addLeadingZero(Number(this.inputMinutes.value)); - } - setHoursDefault() { - this.hours = new Date().getHours(); - this.inputHours.value = (this.hours % (this.options.twelveHour ? 12 : 24)).toString(); - } - done = (clearValue = null) => { - // Set input value - const last = this.el.value; - let value = clearValue - ? '' - : Timepicker._addLeadingZero(this.hours) + ':' + Timepicker._addLeadingZero(this.minutes); - this.time = value; - if (!clearValue && this.options.twelveHour) { - value = `${value} ${this.amOrPm}`; - } - this.el.value = value; - // Trigger change event - if (value !== last) { - this.el.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); - } - }; - confirm = () => { - this.done(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onDone === 'function') - this.options.onDone.call(this); - }; - cancel = () => { - // not logical clearing the input field on cancel, since the end user might want to make use of the previously submitted value - // this.clear(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onCancel === 'function') - this.options.onCancel.call(this); - }; - clear = () => { - // @todo should clear timepicker hour/minute input elems and reset analog clock, currently clears input el - this.done(true); - }; - // deprecated - open() { - console.warn('Timepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - close() { - console.warn('Timepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - static { - Timepicker._template = `
-
-
-
-
- -
-
- : -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
`; - } -} - -const _defaults$7 = { - text: '', - displayLength: 4000, - inDuration: 300, - outDuration: 375, - classes: '', - completeCallback: null, - activationPercent: 0.8 -}; -class Toast { - /** The toast element. */ - el; - /** - * The remaining amount of time in ms that the toast - * will stay before dismissal. - */ - timeRemaining; - /** - * Describes the current pan state of the Toast. - */ - panning; - options; - message; - counterInterval; - wasSwiped; - startingXPos; - xPos; - time; - deltaX; - velocityX; - static _toasts; - static _container; - static _draggedToast; - constructor(options) { - this.options = { - ...Toast.defaults, - ...options - }; - this.message = this.options.text; - this.panning = false; - this.timeRemaining = this.options.displayLength; - if (Toast._toasts.length === 0) { - Toast._createContainer(); - } - // Create new toast - Toast._toasts.push(this); - const toastElement = this._createToast(); - toastElement['M_Toast'] = this; - this.el = toastElement; - this._animateIn(); - this._setTimer(); - } - static get defaults() { - return _defaults$7; - } - static getInstance(el) { - return el['M_Toast']; - } - static _createContainer() { - const container = document.createElement('div'); - container.setAttribute('id', 'toast-container'); - // Add event handler - container.addEventListener('touchstart', Toast._onDragStart); - container.addEventListener('touchmove', Toast._onDragMove); - container.addEventListener('touchend', Toast._onDragEnd); - container.addEventListener('mousedown', Toast._onDragStart); - document.addEventListener('mousemove', Toast._onDragMove); - document.addEventListener('mouseup', Toast._onDragEnd); - document.body.appendChild(container); - Toast._container = container; - } - static _removeContainer() { - document.removeEventListener('mousemove', Toast._onDragMove); - document.removeEventListener('mouseup', Toast._onDragEnd); - if (Toast._container) { - Toast._container.remove(); - Toast._container = null; - } - } - static _onDragStart(e) { - if (e.target && e.target.closest('.toast')) { - const toastElem = e.target.closest('.toast'); - const toast = toastElem['M_Toast']; - toast.panning = true; - Toast._draggedToast = toast; - toast.el.classList.add('panning'); - toast.el.style.transition = ''; - toast.startingXPos = Toast._xPos(e); - toast.time = Date.now(); - toast.xPos = Toast._xPos(e); - } - } - static _onDragMove(e) { - if (!!Toast._draggedToast) { - e.preventDefault(); - const toast = Toast._draggedToast; - toast.deltaX = Math.abs(toast.xPos - Toast._xPos(e)); - toast.xPos = Toast._xPos(e); - toast.velocityX = toast.deltaX / (Date.now() - toast.time); - toast.time = Date.now(); - const totalDeltaX = toast.xPos - toast.startingXPos; - const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; - toast.el.style.transform = `translateX(${totalDeltaX}px)`; - toast.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString(); - } - } - static _onDragEnd() { - if (!!Toast._draggedToast) { - const toast = Toast._draggedToast; - toast.panning = false; - toast.el.classList.remove('panning'); - const totalDeltaX = toast.xPos - toast.startingXPos; - const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; - const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || toast.velocityX > 1; - // Remove toast - if (shouldBeDismissed) { - toast.wasSwiped = true; - toast.dismiss(); - // Animate toast back to original position - } - else { - toast.el.style.transition = 'transform .2s, opacity .2s'; - toast.el.style.transform = ''; - toast.el.style.opacity = ''; - } - Toast._draggedToast = null; - } - } - static _xPos(e) { - if (e.type.startsWith('touch') && e.targetTouches.length >= 1) { - return e.targetTouches[0].clientX; - } - // mouse event - return e.clientX; - } - /** - * dismiss all toasts. - */ - static dismissAll() { - for (const toastIndex in Toast._toasts) { - Toast._toasts[toastIndex].dismiss(); - } - } - _createToast() { - let toast = this.options.toastId - ? document.getElementById(this.options.toastId) - : document.createElement('div'); - if (toast instanceof HTMLTemplateElement) { - const node = toast.content.cloneNode(true); - toast = node.firstElementChild; - } - toast.classList.add('toast'); - toast.setAttribute('role', 'alert'); - toast.setAttribute('aria-live', 'assertive'); - toast.setAttribute('aria-atomic', 'true'); - // Add custom classes onto toast - if (this.options.classes.length > 0) { - toast.classList.add(...this.options.classes.split(' ')); - } - if (this.message) - toast.innerText = this.message; - if (Toast._container) { - Toast._container.appendChild(toast); - } - return toast; - } - _animateIn() { - // Animate toast in - this.el.style.display = ''; - this.el.style.opacity = '0'; - // easeOutCubic - this.el.style.transition = ` - top ${this.options.inDuration}ms ease, - opacity ${this.options.inDuration}ms ease - `; - setTimeout(() => { - this.el.style.top = '0'; - this.el.style.opacity = '1'; - }, 1); - } - /** - * Create setInterval which automatically removes toast when timeRemaining >= 0 - * has been reached. - */ - _setTimer() { - if (this.timeRemaining !== Infinity) { - this.counterInterval = setInterval(() => { - // If toast is not being dragged, decrease its time remaining - if (!this.panning) { - this.timeRemaining -= 20; - } - // Animate toast out - if (this.timeRemaining <= 0) { - this.dismiss(); - } - }, 20); - } - } - /** - * Dismiss toast with animation. - */ - dismiss() { - clearInterval(this.counterInterval); - const activationDistance = this.el.offsetWidth * this.options.activationPercent; - if (this.wasSwiped) { - this.el.style.transition = 'transform .05s, opacity .05s'; - this.el.style.transform = `translateX(${activationDistance}px)`; - this.el.style.opacity = '0'; - } - // easeOutExpo - this.el.style.transition = ` - margin ${this.options.outDuration}ms ease, - opacity ${this.options.outDuration}ms ease`; - setTimeout(() => { - this.el.style.opacity = '0'; - this.el.style.marginTop = '-40px'; - }, 1); - setTimeout(() => { - // Call the optional callback - if (typeof this.options.completeCallback === 'function') { - this.options.completeCallback(); - } - // Remove toast from DOM - if (this.el.id != this.options.toastId) { - this.el.remove(); - Toast._toasts.splice(Toast._toasts.indexOf(this), 1); - if (Toast._toasts.length === 0) { - Toast._removeContainer(); - } - } - }, this.options.outDuration); - } - static { - Toast._toasts = []; - Toast._container = null; - Toast._draggedToast = null; - } -} - -const _defaults$6 = { - exitDelay: 200, - enterDelay: 0, - text: '', - margin: 5, - inDuration: 250, - outDuration: 200, - position: 'bottom', - transitionMovement: 10, - opacity: 1 -}; -class Tooltip extends Component { - /** - * If tooltip is open. - */ - isOpen; - /** - * If tooltip is hovered. - */ - isHovered; - /** - * If tooltip is focused. - */ - isFocused; - tooltipEl; - _exitDelayTimeout; - _enterDelayTimeout; - xMovement; - yMovement; - constructor(el, options) { - super(el, options, Tooltip); - this.el['M_Tooltip'] = this; - this.options = { - ...Tooltip.defaults, - ...this._getAttributeOptions(), - ...options - }; - this.isOpen = false; - this.isHovered = false; - this.isFocused = false; - this._appendTooltipEl(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$6; - } - /** - * Initializes instances of Tooltip. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Tooltip); - } - static getInstance(el) { - return el['M_Tooltip']; - } - destroy() { - this.tooltipEl.remove(); - this._removeEventHandlers(); - this.el['M_Tooltip'] = undefined; - } - _appendTooltipEl() { - this.tooltipEl = document.createElement('div'); - this.tooltipEl.classList.add('material-tooltip'); - const tooltipContentEl = this.options.tooltipId - ? document.getElementById(this.options.tooltipId) - : document.createElement('div'); - this.tooltipEl.append(tooltipContentEl); - tooltipContentEl.style.display = ''; - tooltipContentEl.classList.add('tooltip-content'); - this._setTooltipContent(tooltipContentEl); - this.tooltipEl.appendChild(tooltipContentEl); - document.body.appendChild(this.tooltipEl); - } - _setTooltipContent(tooltipContentEl) { - if (this.options.tooltipId) - return; - tooltipContentEl.innerText = this.options.text; - } - _updateTooltipContent() { - this._setTooltipContent(this.tooltipEl.querySelector('.tooltip-content')); - } - _setupEventHandlers() { - this.el.addEventListener('mouseenter', this._handleMouseEnter); - this.el.addEventListener('mouseleave', this._handleMouseLeave); - this.el.addEventListener('focus', this._handleFocus, true); - this.el.addEventListener('blur', this._handleBlur, true); - } - _removeEventHandlers() { - this.el.removeEventListener('mouseenter', this._handleMouseEnter); - this.el.removeEventListener('mouseleave', this._handleMouseLeave); - this.el.removeEventListener('focus', this._handleFocus, true); - this.el.removeEventListener('blur', this._handleBlur, true); - } - /** - * Show tooltip. - */ - open = (isManual) => { - if (this.isOpen) - return; - isManual = isManual === undefined ? true : undefined; // Default value true - this.isOpen = true; - // Update tooltip content with HTML attribute options - this.options = { ...this.options, ...this._getAttributeOptions() }; - this._updateTooltipContent(); - this._setEnterDelayTimeout(isManual); - }; - /** - * Hide tooltip. - */ - close = () => { - if (!this.isOpen) - return; - this.isHovered = false; - this.isFocused = false; - this.isOpen = false; - this._setExitDelayTimeout(); - }; - _setExitDelayTimeout() { - clearTimeout(this._exitDelayTimeout); - this._exitDelayTimeout = setTimeout(() => { - if (this.isHovered || this.isFocused) - return; - this._animateOut(); - }, this.options.exitDelay); - } - _setEnterDelayTimeout(isManual) { - clearTimeout(this._enterDelayTimeout); - this._enterDelayTimeout = setTimeout(() => { - if (!this.isHovered && !this.isFocused && !isManual) - return; - this._animateIn(); - }, this.options.enterDelay); - } - _positionTooltip() { - const tooltip = this.tooltipEl; - const origin = this.el, originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, tooltipHeight = tooltip.offsetHeight, tooltipWidth = tooltip.offsetWidth, margin = this.options.margin; - this.xMovement = 0; - this.yMovement = 0; - let targetTop = origin.getBoundingClientRect().top + Utils.getDocumentScrollTop(); - let targetLeft = origin.getBoundingClientRect().left + Utils.getDocumentScrollLeft(); - if (this.options.position === 'top') { - targetTop += -tooltipHeight - margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = -this.options.transitionMovement; - } - else if (this.options.position === 'right') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += originWidth + margin; - this.xMovement = this.options.transitionMovement; - } - else if (this.options.position === 'left') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += -tooltipWidth - margin; - this.xMovement = -this.options.transitionMovement; - } - else { - targetTop += originHeight + margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = this.options.transitionMovement; - } - const newCoordinates = this._repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); - tooltip.style.top = newCoordinates.y + 'px'; - tooltip.style.left = newCoordinates.x + 'px'; - } - _repositionWithinScreen(x, y, width, height) { - const scrollLeft = Utils.getDocumentScrollLeft(); - const scrollTop = Utils.getDocumentScrollTop(); - let newX = x - scrollLeft; - let newY = y - scrollTop; - const bounding = { - left: newX, - top: newY, - width: width, - height: height - }; - const offset = this.options.margin + this.options.transitionMovement; - const edges = Utils.checkWithinContainer(document.body, bounding, offset); - if (edges.left) { - newX = offset; - } - else if (edges.right) { - newX -= newX + width - window.innerWidth; - } - if (edges.top) { - newY = offset; - } - else if (edges.bottom) { - newY -= newY + height - window.innerHeight; - } - return { - x: newX + scrollLeft, - y: newY + scrollTop - }; - } - _animateIn() { - this._positionTooltip(); - this.tooltipEl.style.visibility = 'visible'; - const duration = this.options.inDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`; - this.tooltipEl.style.opacity = (this.options.opacity || 1).toString(); - }, 1); - } - _animateOut() { - const duration = this.options.outDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`; - this.tooltipEl.style.opacity = '0'; - }, 1); - /* - anim.remove(this.tooltipEl); - anim({ - targets: this.tooltipEl, - opacity: 0, - translateX: 0, - translateY: 0, - duration: this.options.outDuration, - easing: 'easeOutCubic' - }); - */ - } - _handleMouseEnter = () => { - this.isHovered = true; - this.isFocused = false; // Allows close of tooltip when opened by focus. - this.open(false); - }; - _handleMouseLeave = () => { - this.isHovered = false; - this.isFocused = false; // Allows close of tooltip when opened by focus. - this.close(); - }; - _handleFocus = () => { - if (Utils.tabPressed) { - this.isFocused = true; - this.open(false); - } - }; - _handleBlur = () => { - this.isFocused = false; - this.close(); - }; - _getAttributeOptions() { - const attributeOptions = {}; - const tooltipTextOption = this.el.getAttribute('data-tooltip'); - const tooltipId = this.el.getAttribute('data-tooltip-id'); - const positionOption = this.el.getAttribute('data-position'); - if (tooltipTextOption) { - attributeOptions.text = tooltipTextOption; - } - if (positionOption) { - attributeOptions.position = positionOption; - } - if (tooltipId) { - attributeOptions.tooltipId = tooltipId; - } - return attributeOptions; - } -} - -const _defaults$5 = {}; -// TODO: !!!!! -class Range extends Component { - _mousedown; - value; - thumb; - constructor(el, options) { - super(el, options, Range); - this.el['M_Range'] = this; - this.options = { - ...Range.defaults, - ...options - }; - this._mousedown = false; - this._setupThumb(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$5; - } - /** - * Initializes instances of Range. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Range); - } - static getInstance(el) { - return el['M_Range']; - } - destroy() { - this._removeEventHandlers(); - this._removeThumb(); - this.el['M_Range'] = undefined; - } - _setupEventHandlers() { - this.el.addEventListener('change', this._handleRangeChange); - this.el.addEventListener('mousedown', this._handleRangeMousedownTouchstart); - this.el.addEventListener('touchstart', this._handleRangeMousedownTouchstart); - this.el.addEventListener('input', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('mousemove', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('touchmove', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('mouseup', this._handleRangeMouseupTouchend); - this.el.addEventListener('touchend', this._handleRangeMouseupTouchend); - this.el.addEventListener('blur', this._handleRangeBlurMouseoutTouchleave); - this.el.addEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave); - this.el.addEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave); - } - _removeEventHandlers() { - this.el.removeEventListener('change', this._handleRangeChange); - this.el.removeEventListener('mousedown', this._handleRangeMousedownTouchstart); - this.el.removeEventListener('touchstart', this._handleRangeMousedownTouchstart); - this.el.removeEventListener('input', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('mousemove', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('touchmove', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('mouseup', this._handleRangeMouseupTouchend); - this.el.removeEventListener('touchend', this._handleRangeMouseupTouchend); - this.el.removeEventListener('blur', this._handleRangeBlurMouseoutTouchleave); - this.el.removeEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave); - this.el.removeEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave); - } - _handleRangeChange = () => { - this.value.innerHTML = this.el.value; - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - }; - _handleRangeMousedownTouchstart = (e) => { - // Set indicator value - this.value.innerHTML = this.el.value; - this._mousedown = true; - this.el.classList.add('active'); - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - if (e.type !== 'input') { - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - } - }; - _handleRangeInputMousemoveTouchmove = () => { - if (this._mousedown) { - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - this.value.innerHTML = this.el.value; - } - }; - _handleRangeMouseupTouchend = () => { - this._mousedown = false; - this.el.classList.remove('active'); - }; - _handleRangeBlurMouseoutTouchleave = () => { - if (!this._mousedown) { - const paddingLeft = parseInt(getComputedStyle(this.el).paddingLeft); - const marginLeftText = 7 + paddingLeft + 'px'; - if (this.thumb.classList.contains('active')) { - const duration = 100; - // from - this.thumb.style.transition = 'none'; - setTimeout(() => { - this.thumb.style.transition = ` - height ${duration}ms ease, - width ${duration}ms ease, - top ${duration}ms ease, - margin ${duration}ms ease - `; - // to - this.thumb.style.height = '0'; - this.thumb.style.width = '0'; - this.thumb.style.top = '0'; - this.thumb.style.marginLeft = marginLeftText; - }, 1); - } - this.thumb.classList.remove('active'); - } - }; - _setupThumb() { - this.thumb = document.createElement('span'); - this.value = document.createElement('span'); - this.thumb.classList.add('thumb'); - this.value.classList.add('value'); - this.thumb.append(this.value); - this.el.after(this.thumb); - } - _removeThumb() { - this.thumb.remove(); - } - _showRangeBubble() { - const paddingLeft = parseInt(getComputedStyle(this.thumb.parentElement).paddingLeft); - const marginLeftText = -7 + paddingLeft + 'px'; // TODO: fix magic number? - const duration = 300; - // easeOutQuint - this.thumb.style.transition = ` - height ${duration}ms ease, - width ${duration}ms ease, - top ${duration}ms ease, - margin ${duration}ms ease - `; - // to - this.thumb.style.height = '30px'; - this.thumb.style.width = '30px'; - this.thumb.style.top = '-30px'; - this.thumb.style.marginLeft = marginLeftText; - } - _calcRangeOffset() { - const width = this.el.getBoundingClientRect().width - 15; - const max = parseFloat(this.el.getAttribute('max')) || 100; // Range default max - const min = parseFloat(this.el.getAttribute('min')) || 0; // Range default min - const percent = (parseFloat(this.el.value) - min) / (max - min); - return percent * width; - } - /** - * Initializes every range input in the current document. - */ - static Init() { - if (typeof document !== 'undefined') - Range.init(document?.querySelectorAll('input[type=range]'), {}); - } -} - -const _defaults$4 = { - onOpen: null, - onClose: null -}; -class TapTarget extends Component { - /** - * If the tap target is open. - */ - isOpen; - static _taptargets; - wrapper; - // private _origin: HTMLElement; - originEl; - waveEl; - contentEl; - constructor(el, options) { - super(el, options, TapTarget); - this.el['M_TapTarget'] = this; - this.options = { - ...TapTarget.defaults, - ...options - }; - this.isOpen = false; - // setup - this.originEl = document.querySelector(`#${el.dataset.target}`); - this.originEl.tabIndex = 0; - this._setup(); - this._calculatePositioning(); - this._setupEventHandlers(); - TapTarget._taptargets.push(this); - } - static get defaults() { - return _defaults$4; - } - /** - * Initializes instances of TapTarget. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, TapTarget); - } - static getInstance(el) { - return el['M_TapTarget']; - } - destroy() { - this._removeEventHandlers(); - this.el['M_TapTarget'] = undefined; - const index = TapTarget._taptargets.indexOf(this); - if (index >= 0) { - TapTarget._taptargets.splice(index, 1); - } - } - _setupEventHandlers() { - this.originEl.addEventListener('click', this._handleTargetToggle); - this.originEl.addEventListener('keypress', this._handleKeyboardInteraction, true); - // this.originEl.addEventListener('click', this._handleOriginClick); - // Resize - window.addEventListener('resize', this._handleThrottledResize); - } - _removeEventHandlers() { - this.originEl.removeEventListener('click', this._handleTargetToggle); - this.originEl.removeEventListener('keypress', this._handleKeyboardInteraction, true); - // this.originEl.removeEventListener('click', this._handleOriginClick); - window.removeEventListener('resize', this._handleThrottledResize); - } - _handleThrottledResize = () => Utils.throttle(this._handleResize, 200).bind(this); - _handleKeyboardInteraction = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleTargetToggle(); - } - }; - _handleTargetToggle = () => { - if (!this.isOpen) - this.open(); - else - this.close(); - }; - /*_handleOriginClick = () => { - this.close(); - }*/ - _handleResize = () => { - this._calculatePositioning(); - }; - _handleDocumentClick = (e) => { - if (e.target.closest(`#${this.el.dataset.target}`) !== this.originEl && - !e.target.closest('.tap-target-wrapper')) { - this.close(); - // e.preventDefault(); - // e.stopPropagation(); - } - }; - _setup() { - // Creating tap target - this.wrapper = this.el.parentElement; - this.waveEl = this.wrapper.querySelector('.tap-target-wave'); - this.el.parentElement.ariaExpanded = 'false'; - this.originEl.style.zIndex = '1002'; - // this.originEl = this.wrapper.querySelector('.tap-target-origin'); - this.contentEl = this.el.querySelector('.tap-target-content'); - // Creating wrapper - if (!this.wrapper.classList.contains('.tap-target-wrapper')) { - this.wrapper = document.createElement('div'); - this.wrapper.classList.add('tap-target-wrapper'); - this.el.before(this.wrapper); - this.wrapper.append(this.el); - } - // Creating content - if (!this.contentEl) { - this.contentEl = document.createElement('div'); - this.contentEl.classList.add('tap-target-content'); - this.el.append(this.contentEl); - } - // Creating foreground wave - if (!this.waveEl) { - this.waveEl = document.createElement('div'); - this.waveEl.classList.add('tap-target-wave'); - // Creating origin - /*if (!this.originEl) { - this.originEl = this._origin.cloneNode(true); // .clone(true, true); - this.originEl.classList.add('tap-target-origin'); - this.originEl.removeAttribute('id'); - this.originEl.removeAttribute('style'); - this.waveEl.append(this.originEl); - }*/ - this.wrapper.append(this.waveEl); - } - } - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - _calculatePositioning() { - // Element or parent is fixed position? - let isFixed = getComputedStyle(this.originEl).position === 'fixed'; - if (!isFixed) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let currentElem = this.originEl; - const parents = []; - while ((currentElem = currentElem.parentNode) && currentElem !== document) - parents.push(currentElem); - for (let i = 0; i < parents.length; i++) { - isFixed = getComputedStyle(parents[i]).position === 'fixed'; - if (isFixed) - break; - } - } - // Calculating origin - const originWidth = this.originEl.offsetWidth; - const originHeight = this.originEl.offsetHeight; - const originTop = isFixed - ? this._offset(this.originEl).top - Utils.getDocumentScrollTop() - : this._offset(this.originEl).top; - const originLeft = isFixed - ? this._offset(this.originEl).left - Utils.getDocumentScrollLeft() - : this._offset(this.originEl).left; - // Calculating screen - const windowWidth = window.innerWidth; - const windowHeight = window.innerHeight; - const scrollBarWidth = windowWidth - document.documentElement.clientWidth; - const centerX = windowWidth / 2; - const centerY = windowHeight / 2; - const isLeft = originLeft <= centerX; - const isRight = originLeft > centerX; - const isTop = originTop <= centerY; - const isBottom = originTop > centerY; - const isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75; - // Calculating tap target - const tapTargetWidth = this.el.offsetWidth; - const tapTargetHeight = this.el.offsetHeight; - const tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2; - const tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2; - const tapTargetPosition = isFixed ? 'fixed' : 'absolute'; - // Calculating content - const tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth; - const tapTargetTextHeight = tapTargetHeight / 2; - const tapTargetTextTop = isTop ? tapTargetHeight / 2 : 0; - const tapTargetTextBottom = 0; - const tapTargetTextLeft = isLeft && !isCenterX ? tapTargetWidth / 2 - originWidth : 0; - const tapTargetTextRight = 0; - const tapTargetTextPadding = originWidth; - const tapTargetTextAlign = isBottom ? 'bottom' : 'top'; - // Calculating wave - const tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2; - const tapTargetWaveHeight = tapTargetWaveWidth; - const tapTargetWaveTop = tapTargetHeight / 2 - tapTargetWaveHeight / 2; - const tapTargetWaveLeft = tapTargetWidth / 2 - tapTargetWaveWidth / 2; - // Setting tap target - this.wrapper.style.top = isTop ? tapTargetTop + 'px' : ''; - this.wrapper.style.right = isRight - ? windowWidth - tapTargetLeft - tapTargetWidth - scrollBarWidth + 'px' - : ''; - this.wrapper.style.bottom = isBottom - ? windowHeight - tapTargetTop - tapTargetHeight + 'px' - : ''; - this.wrapper.style.left = isLeft ? tapTargetLeft + 'px' : ''; - this.wrapper.style.position = tapTargetPosition; - // Setting content - this.contentEl.style.width = tapTargetTextWidth + 'px'; - this.contentEl.style.height = tapTargetTextHeight + 'px'; - this.contentEl.style.top = tapTargetTextTop + 'px'; - this.contentEl.style.right = tapTargetTextRight + 'px'; - this.contentEl.style.bottom = tapTargetTextBottom + 'px'; - this.contentEl.style.left = tapTargetTextLeft + 'px'; - this.contentEl.style.padding = tapTargetTextPadding + 'px'; - this.contentEl.style.verticalAlign = tapTargetTextAlign; - // Setting wave - this.waveEl.style.top = tapTargetWaveTop + 'px'; - this.waveEl.style.left = tapTargetWaveLeft + 'px'; - this.waveEl.style.width = tapTargetWaveWidth + 'px'; - this.waveEl.style.height = tapTargetWaveHeight + 'px'; - } - /** - * Open Tap Target. - */ - open = () => { - if (this.isOpen) - return; - // onOpen callback - if (typeof this.options.onOpen === 'function') { - this.options.onOpen.call(this, this.originEl); - } - this.isOpen = true; - this.wrapper.classList.add('open'); - this.wrapper.ariaExpanded = 'true'; - document.body.addEventListener('click', this._handleDocumentClick, true); - document.body.addEventListener('keypress', this._handleDocumentClick, true); - document.body.addEventListener('touchend', this._handleDocumentClick); - }; - /** - * Close Tap Target. - */ - close = () => { - if (!this.isOpen) - return; - // onClose callback - if (typeof this.options.onClose === 'function') { - this.options.onClose.call(this, this.originEl); - } - this.isOpen = false; - this.wrapper.classList.remove('open'); - this.wrapper.ariaExpanded = 'false'; - document.body.removeEventListener('click', this._handleDocumentClick, true); - document.body.removeEventListener('keypress', this._handleDocumentClick, true); - document.body.removeEventListener('touchend', this._handleDocumentClick); - }; - static { - TapTarget._taptargets = []; - } -} - -const _defaults$3 = Object.freeze({}); -class CharacterCounter extends Component { - /** Stores the reference to the counter HTML element. */ - counterEl; - /** Specifies whether the input is valid or not. */ - isInvalid; - /** Specifies whether the input text has valid length or not. */ - isValidLength; - constructor(el, options) { - super(el, {}, CharacterCounter); - this.el['M_CharacterCounter'] = this; - this.options = { - ...CharacterCounter.defaults, - ...options - }; - this.isInvalid = false; - this.isValidLength = false; - this._setupCounter(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$3; - } - /** - * Initializes instances of CharacterCounter. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, CharacterCounter); - } - static getInstance(el) { - return el['M_CharacterCounter']; - } - destroy() { - this._removeEventHandlers(); - this.el['CharacterCounter'] = undefined; - this._removeCounter(); - } - _setupEventHandlers() { - this.el.addEventListener('focus', this.updateCounter, true); - this.el.addEventListener('input', this.updateCounter, true); - } - _removeEventHandlers() { - this.el.removeEventListener('focus', this.updateCounter, true); - this.el.removeEventListener('input', this.updateCounter, true); - } - _setupCounter() { - this.counterEl = document.createElement('span'); - this.counterEl.classList.add('character-counter'); - this.counterEl.style.float = 'right'; - this.counterEl.style.fontSize = '12px'; - this.counterEl.style.height = '1'; - this.el.parentElement.appendChild(this.counterEl); - } - _removeCounter() { - this.counterEl.remove(); - } - updateCounter = () => { - const maxLength = parseInt(this.el.getAttribute('maxlength')), actualLength = this.el.value.length; - this.isValidLength = actualLength <= maxLength; - let counterString = actualLength.toString(); - if (maxLength) { - counterString += '/' + maxLength; - this._validateInput(); - } - this.counterEl.innerHTML = counterString; - }; - _validateInput() { - if (this.isValidLength && this.isInvalid) { - this.isInvalid = false; - this.el.classList.remove('invalid'); - } - else if (!this.isValidLength && !this.isInvalid) { - this.isInvalid = true; - this.el.classList.remove('valid'); - this.el.classList.add('invalid'); - } - } -} - -const _defaults$2 = { - responsiveThreshold: 0 // breakpoint for swipeable -}; -class Parallax extends Component { - _enabled; - _img; - static _parallaxes = []; - static _handleScrollThrottled; - static _handleWindowResizeThrottled; - constructor(el, options) { - super(el, options, Parallax); - this.el['M_Parallax'] = this; - this.options = { - ...Parallax.defaults, - ...options - }; - this._enabled = window.innerWidth > this.options.responsiveThreshold; - this._img = this.el.querySelector('img'); - this._updateParallax(); - this._setupEventHandlers(); - this._setupStyles(); - Parallax._parallaxes.push(this); - } - static get defaults() { - return _defaults$2; - } - /** - * Initializes instances of Parallax. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Parallax); - } - static getInstance(el) { - return el['M_Parallax']; - } - destroy() { - Parallax._parallaxes.splice(Parallax._parallaxes.indexOf(this), 1); - this._img.style.transform = ''; - this._removeEventHandlers(); - this.el['M_Parallax'] = undefined; - } - static _handleScroll() { - for (let i = 0; i < Parallax._parallaxes.length; i++) { - const parallaxInstance = Parallax._parallaxes[i]; - parallaxInstance._updateParallax.call(parallaxInstance); - } - } - static _handleWindowResize() { - for (let i = 0; i < Parallax._parallaxes.length; i++) { - const parallaxInstance = Parallax._parallaxes[i]; - parallaxInstance._enabled = window.innerWidth > parallaxInstance.options.responsiveThreshold; - } - } - _setupEventHandlers() { - this._img.addEventListener('load', this._handleImageLoad); - if (Parallax._parallaxes.length === 0) { - if (!Parallax._handleScrollThrottled) { - Parallax._handleScrollThrottled = Utils.throttle(Parallax._handleScroll, 5); - } - if (!Parallax._handleWindowResizeThrottled) { - Parallax._handleWindowResizeThrottled = Utils.throttle(Parallax._handleWindowResize, 5); - } - window.addEventListener('scroll', Parallax._handleScrollThrottled); - window.addEventListener('resize', Parallax._handleWindowResizeThrottled); - } - } - _removeEventHandlers() { - this._img.removeEventListener('load', this._handleImageLoad); - if (Parallax._parallaxes.length === 0) { - window.removeEventListener('scroll', Parallax._handleScrollThrottled); - window.removeEventListener('resize', Parallax._handleWindowResizeThrottled); - } - } - _setupStyles() { - this._img.style.opacity = '1'; - } - _handleImageLoad = () => { - this._updateParallax(); - }; - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.scrollY - docElem.clientTop, - left: box.left + window.scrollX - docElem.clientLeft - }; - } - _updateParallax() { - const containerHeight = this.el.getBoundingClientRect().height > 0 ? this.el.parentElement.offsetHeight : 500; - const imgHeight = this._img.offsetHeight; - const parallaxDist = imgHeight - containerHeight; - const bottom = this._offset(this.el).top + containerHeight; - const top = this._offset(this.el).top; - const scrollTop = Utils.getDocumentScrollTop(); - const windowHeight = window.innerHeight; - const windowBottom = scrollTop + windowHeight; - const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight); - const parallax = parallaxDist * percentScrolled; - if (!this._enabled) { - this._img.style.transform = ''; - } - else if (bottom > scrollTop && top < scrollTop + windowHeight) { - this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`; - } - } -} - -const _defaults$1 = { - top: 0, - bottom: Infinity, - offset: 0, - onPositionChange: null -}; -class Pushpin extends Component { - static _pushpins; - originalOffset; - constructor(el, options) { - super(el, options, Pushpin); - this.el['M_Pushpin'] = this; - this.options = { - ...Pushpin.defaults, - ...options - }; - this.originalOffset = this.el.offsetTop; - Pushpin._pushpins.push(this); - this._setupEventHandlers(); - this._updatePosition(); - } - static get defaults() { - return _defaults$1; - } - /** - * Initializes instances of Pushpin. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Pushpin); - } - static getInstance(el) { - return el['M_Pushpin']; - } - destroy() { - this.el.style.top = null; - this._removePinClasses(); - // Remove pushpin Inst - const index = Pushpin._pushpins.indexOf(this); - Pushpin._pushpins.splice(index, 1); - if (Pushpin._pushpins.length === 0) { - this._removeEventHandlers(); - } - this.el['M_Pushpin'] = undefined; - } - static _updateElements() { - for (const elIndex in Pushpin._pushpins) { - const pInstance = Pushpin._pushpins[elIndex]; - pInstance._updatePosition(); - } - } - _setupEventHandlers() { - document.addEventListener('scroll', Pushpin._updateElements); - } - _removeEventHandlers() { - document.removeEventListener('scroll', Pushpin._updateElements); - } - _updatePosition() { - const scrolled = Utils.getDocumentScrollTop() + this.options.offset; - if (this.options.top <= scrolled && - this.options.bottom >= scrolled && - !this.el.classList.contains('pinned')) { - this._removePinClasses(); - this.el.style.top = `${this.options.offset}px`; - this.el.classList.add('pinned'); - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pinned'); - } - } - // Add pin-top (when scrolled position is above top) - if (scrolled < this.options.top && !this.el.classList.contains('pin-top')) { - this._removePinClasses(); - this.el.style.top = '0'; - this.el.classList.add('pin-top'); - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pin-top'); - } - } - // Add pin-bottom (when scrolled position is below bottom) - if (scrolled > this.options.bottom && !this.el.classList.contains('pin-bottom')) { - this._removePinClasses(); - this.el.classList.add('pin-bottom'); - this.el.style.top = `${this.options.bottom - this.originalOffset}px`; - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pin-bottom'); - } - } - } - _removePinClasses() { - // IE 11 bug (can't remove multiple classes in one line) - this.el.classList.remove('pin-top'); - this.el.classList.remove('pinned'); - this.el.classList.remove('pin-bottom'); - } - static { - Pushpin._pushpins = []; - } -} - -const _defaults = { - throttle: 100, - scrollOffset: 200, // offset - 200 allows elements near bottom of page to scroll - activeClass: 'active', - getActiveElement: (id) => { - return 'a[href="#' + id + '"]'; - }, - keepTopElementActive: false, - animationDuration: null -}; -class ScrollSpy extends Component { - static _elements; - static _count; - static _increment; - static _elementsInView; - static _visibleElements; - static _ticks; - static _keptTopActiveElement = null; - tickId; - id; - constructor(el, options) { - super(el, options, ScrollSpy); - this.el['M_ScrollSpy'] = this; - this.options = { - ...ScrollSpy.defaults, - ...options - }; - ScrollSpy._elements.push(this); - ScrollSpy._count++; - ScrollSpy._increment++; - this.tickId = -1; - this.id = ScrollSpy._increment.toString(); - this._setupEventHandlers(); - this._handleWindowScroll(); - } - static get defaults() { - return _defaults; - } - /** - * Initializes instances of ScrollSpy. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, ScrollSpy); - } - static getInstance(el) { - return el['M_ScrollSpy']; - } - destroy() { - ScrollSpy._elements.splice(ScrollSpy._elements.indexOf(this), 1); - ScrollSpy._elementsInView.splice(ScrollSpy._elementsInView.indexOf(this), 1); - ScrollSpy._visibleElements.splice(ScrollSpy._visibleElements.indexOf(this.el), 1); - ScrollSpy._count--; - this._removeEventHandlers(); - const actElem = document.querySelector(this.options.getActiveElement(this.el.id)); - actElem.classList.remove(this.options.activeClass); - this.el['M_ScrollSpy'] = undefined; - } - _setupEventHandlers() { - if (ScrollSpy._count === 1) { - window.addEventListener('scroll', this._handleWindowScroll); - window.addEventListener('resize', this._handleThrottledResize); - document.body.addEventListener('click', this._handleTriggerClick); - } - } - _removeEventHandlers() { - if (ScrollSpy._count === 0) { - window.removeEventListener('scroll', this._handleWindowScroll); - window.removeEventListener('resize', this._handleThrottledResize); - document.body.removeEventListener('click', this._handleTriggerClick); - } - } - _handleThrottledResize = () => Utils.throttle(this._handleWindowScroll, 200).bind(this); - _handleTriggerClick = (e) => { - const trigger = e.target; - for (let i = ScrollSpy._elements.length - 1; i >= 0; i--) { - const scrollspy = ScrollSpy._elements[i]; - const x = document.querySelector('a[href="#' + scrollspy.el.id + '"]'); - if (trigger === x) { - e.preventDefault(); - if (scrollspy.el['M_ScrollSpy'].options.animationDuration) { - ScrollSpy._smoothScrollIntoView(scrollspy.el, scrollspy.el['M_ScrollSpy'].options.animationDuration); - } - else { - scrollspy.el.scrollIntoView({ behavior: 'smooth' }); - } - break; - } - } - }; - _handleWindowScroll = () => { - // unique tick id - ScrollSpy._ticks++; - // viewport rectangle - const top = Utils.getDocumentScrollTop(), left = Utils.getDocumentScrollLeft(), right = left + window.innerWidth, bottom = top + window.innerHeight; - // determine which elements are in view - const intersections = ScrollSpy._findElements(top, right, bottom, left); - for (let i = 0; i < intersections.length; i++) { - const scrollspy = intersections[i]; - const lastTick = scrollspy.tickId; - if (lastTick < 0) { - // entered into view - scrollspy._enter(); - } - // update tick id - scrollspy.tickId = ScrollSpy._ticks; - } - for (let i = 0; i < ScrollSpy._elementsInView.length; i++) { - const scrollspy = ScrollSpy._elementsInView[i]; - const lastTick = scrollspy.tickId; - if (lastTick >= 0 && lastTick !== ScrollSpy._ticks) { - // exited from view - scrollspy._exit(); - scrollspy.tickId = -1; - } - } - // remember elements in view for next tick - ScrollSpy._elementsInView = intersections; - if (ScrollSpy._elements.length) { - const options = ScrollSpy._elements[0].el['M_ScrollSpy'].options; - if (options.keepTopElementActive && ScrollSpy._visibleElements.length === 0) { - this._resetKeptTopActiveElementIfNeeded(); - const topElements = ScrollSpy._elements - .filter((value) => ScrollSpy._getDistanceToViewport(value.el) <= 0) - .sort((a, b) => { - const distanceA = ScrollSpy._getDistanceToViewport(a.el); - const distanceB = ScrollSpy._getDistanceToViewport(b.el); - if (distanceA < distanceB) - return -1; - if (distanceA > distanceB) - return 1; - return 0; - }); - const nearestTopElement = topElements.length - ? topElements[topElements.length - 1] - : ScrollSpy._elements[0]; - const actElem = document.querySelector(options.getActiveElement(nearestTopElement.el.id)); - actElem?.classList.add(options.activeClass); - ScrollSpy._keptTopActiveElement = actElem; - } - } - }; - static _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - static _findElements(top, right, bottom, left) { - const hits = []; - for (let i = 0; i < ScrollSpy._elements.length; i++) { - const scrollspy = ScrollSpy._elements[i]; - const currTop = top + scrollspy.options.scrollOffset || 200; - if (scrollspy.el.getBoundingClientRect().height > 0) { - const elTop = ScrollSpy._offset(scrollspy.el).top, elLeft = ScrollSpy._offset(scrollspy.el).left, elRight = elLeft + scrollspy.el.getBoundingClientRect().width, elBottom = elTop + scrollspy.el.getBoundingClientRect().height; - const isIntersect = !(elLeft > right || - elRight < left || - elTop > bottom || - elBottom < currTop); - if (isIntersect) { - hits.push(scrollspy); - } - } - } - return hits; - } - _enter() { - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((value) => value.getBoundingClientRect().height !== 0); - if (ScrollSpy._visibleElements[0]) { - const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id)); - actElem?.classList.remove(this.options.activeClass); - if (ScrollSpy._visibleElements[0]['M_ScrollSpy'] && - this.id < ScrollSpy._visibleElements[0]['M_ScrollSpy'].id) { - ScrollSpy._visibleElements.unshift(this.el); - } - else { - ScrollSpy._visibleElements.push(this.el); - } - } - else { - ScrollSpy._visibleElements.push(this.el); - } - this._resetKeptTopActiveElementIfNeeded(); - const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id); - document.querySelector(selector)?.classList.add(this.options.activeClass); - } - _exit() { - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((value) => value.getBoundingClientRect().height !== 0); - if (ScrollSpy._visibleElements[0]) { - const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id)); - actElem?.classList.remove(this.options.activeClass); - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((x) => x.id != this.el.id); - if (ScrollSpy._visibleElements[0]) { - // Check if empty - const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id); - document.querySelector(selector)?.classList.add(this.options.activeClass); - this._resetKeptTopActiveElementIfNeeded(); - } - } - } - _resetKeptTopActiveElementIfNeeded() { - if (ScrollSpy._keptTopActiveElement) { - ScrollSpy._keptTopActiveElement.classList.remove(this.options.activeClass); - ScrollSpy._keptTopActiveElement = null; - } - } - static _getDistanceToViewport(element) { - const rect = element.getBoundingClientRect(); - const distance = rect.top; - return distance; - } - static _smoothScrollIntoView(element, duration = 300) { - const targetPosition = element.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); - const startPosition = window.scrollY || window.pageYOffset; - const distance = targetPosition - startPosition; - const startTime = performance.now(); - function scrollStep(currentTime) { - const elapsed = currentTime - startTime; - const progress = Math.min(elapsed / duration, 1); - const scrollY = startPosition + distance * progress; - if (progress < 1) { - window.scrollTo(0, scrollY); - requestAnimationFrame(scrollStep); - } - else { - window.scrollTo(0, targetPosition); - } - } - requestAnimationFrame(scrollStep); - } - static { - ScrollSpy._elements = []; - ScrollSpy._elementsInView = []; - ScrollSpy._visibleElements = []; // Array. - ScrollSpy._count = 0; - ScrollSpy._increment = 0; - ScrollSpy._ticks = 0; - } -} - -// type RGBColor = { -// r: number; -// g: number; -// b: number; -// }; - -// type Position = { -// x: number; -// y: number; -// }; - -class Waves { - /** - * - * @param {HTMLElement} el - * @returns - */ - static #offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - - // https://phoenix-dx.com/css-techniques-for-material-ripple-effect/ - - /** - * - * @param {HTMLElement} targetElement - * @param position - * @param color - */ - static renderWaveEffect(targetElement, position = null, color = null) { - const isCentered = position === null; - const duration = 500; - let animationFrame, animationStart; - - const animationStep = (timestamp) => { - if (!animationStart) animationStart = timestamp; - const frame = timestamp - animationStart; - if (frame < duration) { - const easing = (frame / duration) * (2 - frame / duration); - const circle = isCentered - ? 'circle at 50% 50%' - : `circle at ${position.x}px ${position.y}px`; - const waveColor = `rgba(${color?.r || 0}, ${color?.g || 0}, ${color?.b || 0}, ${0.3 * (1 - easing)})`; - const stop = 90 * easing + '%'; - targetElement.style.backgroundImage = - 'radial-gradient(' + - circle + - ', ' + - waveColor + - ' ' + - stop + - ', transparent ' + - stop + - ')'; - animationFrame = window.requestAnimationFrame(animationStep); - } else { - targetElement.style.backgroundImage = 'none'; - window.cancelAnimationFrame(animationFrame); - } - }; - - animationFrame = window.requestAnimationFrame(animationStep); - } - - static Init() { - if (typeof document !== 'undefined') - document?.addEventListener('DOMContentLoaded', () => { - document.body.addEventListener('click', (e) => { - const trigger = e.target; - const el = trigger.closest('.waves-effect'); - if (el && el.contains(trigger)) { - const isCircular = el.classList.contains('waves-circle'); - const x = e.pageX - this.#offset(el).left; - const y = e.pageY - this.#offset(el).top; - let color = null; - if (el.classList.contains('waves-light')) color = { r: 255, g: 255, b: 255 }; - this.renderWaveEffect(el, isCircular ? null : { x, y }, color); - } - }); - }); - } -} - -/* eslint-disable @typescript-eslint/no-unused-vars */ -const version = '2.3.3'; -/** - * Automatically initialize components. - * @param context Root element to initialize. Defaults to `document.body`. - * @param options Options for each component. - */ -function AutoInit(context = document.body, options) { - const registry = { - Autocomplete: context.querySelectorAll('.autocomplete:not(.no-autoinit)'), - Cards: context.querySelectorAll('.cards:not(.no-autoinit)'), - Carousel: context.querySelectorAll('.carousel:not(.no-autoinit)'), - Chips: context.querySelectorAll('.chips:not(.no-autoinit)'), - Collapsible: context.querySelectorAll('.collapsible:not(.no-autoinit)'), - Datepicker: context.querySelectorAll('.datepicker:not(.no-autoinit)'), - Dropdown: context.querySelectorAll('.dropdown-trigger:not(.no-autoinit)'), - Materialbox: context.querySelectorAll('.materialboxed:not(.no-autoinit)'), - Modal: context.querySelectorAll('.modal:not(.no-autoinit)'), - Parallax: context.querySelectorAll('.parallax:not(.no-autoinit)'), - Pushpin: context.querySelectorAll('.pushpin:not(.no-autoinit)'), - ScrollSpy: context.querySelectorAll('.scrollspy:not(.no-autoinit)'), - FormSelect: context.querySelectorAll('select:not(.no-autoinit)'), - Sidenav: context.querySelectorAll('.sidenav:not(.no-autoinit)'), - Tabs: context.querySelectorAll('.tabs:not(.no-autoinit)'), - TapTarget: context.querySelectorAll('.tap-target:not(.no-autoinit)'), - Timepicker: context.querySelectorAll('.timepicker:not(.no-autoinit)'), - Tooltip: context.querySelectorAll('.tooltipped:not(.no-autoinit)'), - FloatingActionButton: context.querySelectorAll('.fixed-action-btn:not(.no-autoinit)') - }; - Autocomplete.init(registry.Autocomplete, options?.Autocomplete ?? {}); - Cards.init(registry.Cards, options?.Cards ?? {}); - Carousel.init(registry.Carousel, options?.Carousel ?? {}); - Chips.init(registry.Chips, options?.Chips ?? {}); - Collapsible.init(registry.Collapsible, options?.Collapsible ?? {}); - Datepicker.init(registry.Datepicker, options?.Datepicker ?? {}); - Dropdown.init(registry.Dropdown, options?.Dropdown ?? {}); - Materialbox.init(registry.Materialbox, options?.Materialbox ?? {}); - Modal.init(registry.Modal, options?.Modal ?? {}); - Parallax.init(registry.Parallax, options?.Parallax ?? {}); - Pushpin.init(registry.Pushpin, options?.Pushpin ?? {}); - ScrollSpy.init(registry.ScrollSpy, options?.ScrollSpy ?? {}); - FormSelect.init(registry.FormSelect, options?.FormSelect ?? {}); - Sidenav.init(registry.Sidenav, options?.Sidenav ?? {}); - Tabs.init(registry.Tabs, options?.Tabs ?? {}); - TapTarget.init(registry.TapTarget, options?.TapTarget ?? {}); - Timepicker.init(registry.Timepicker, options?.Timepicker ?? {}); - Tooltip.init(registry.Tooltip, options?.Tooltip ?? {}); - FloatingActionButton.init(registry.FloatingActionButton, options?.FloatingActionButton ?? {}); -} -// Init -if (typeof document !== 'undefined') { - document.addEventListener('keydown', Utils.docHandleKeydown, true); - document.addEventListener('keyup', Utils.docHandleKeyup, true); - document.addEventListener('focus', Utils.docHandleFocus, true); - document.addEventListener('blur', Utils.docHandleBlur, true); -} -Forms.Init(); -Chips.Init(); -Waves.Init(); -Range.Init(); -Cards.Init(); - -exports.AutoInit = AutoInit; -exports.Autocomplete = Autocomplete; -exports.Cards = Cards; -exports.Carousel = Carousel; -exports.CharacterCounter = CharacterCounter; -exports.Chips = Chips; -exports.Collapsible = Collapsible; -exports.Datepicker = Datepicker; -exports.Dropdown = Dropdown; -exports.FloatingActionButton = FloatingActionButton; -exports.FormSelect = FormSelect; -exports.Forms = Forms; -exports.Materialbox = Materialbox; -exports.Modal = Modal; -exports.Parallax = Parallax; -exports.Pushpin = Pushpin; -exports.Range = Range; -exports.ScrollSpy = ScrollSpy; -exports.Sidenav = Sidenav; -exports.Slider = Slider; -exports.Tabs = Tabs; -exports.TapTarget = TapTarget; -exports.Timepicker = Timepicker; -exports.Toast = Toast; -exports.Tooltip = Tooltip; -exports.Waves = Waves; -exports.version = version; diff --git a/dist/js/materialize.d.ts b/dist/js/materialize.d.ts deleted file mode 100644 index dcfdd7a314..0000000000 --- a/dist/js/materialize.d.ts +++ /dev/null @@ -1,2625 +0,0 @@ -/** - * Base options for component initialization. - */ -interface BaseOptions$1 { -} -type MElement = HTMLElement | Element; -type InitElements = NodeListOf | HTMLCollectionOf; -type ComponentConstructor, O extends BaseOptions$1> = { - new (el: HTMLElement, options: Partial): T; -}; -type ComponentType, O extends BaseOptions$1> = ComponentConstructor & typeof Component; -interface I18nOptions { - cancel: string; - clear: string; - done: string; -} -interface Openable { - isOpen: boolean; - open(): void; - close(): void; -} -/** - * Base class implementation for Materialize components. - */ -declare class Component { - /** - * The DOM element the plugin was initialized with. - */ - el: HTMLElement; - /** - * The options the instance was initialized with. - */ - options: O; - /** - * Constructs component instance and set everything up. - */ - constructor(el: HTMLElement, options: Partial, classDef: ComponentType, O>); - /** - * Initializes component instance. - * @param el HTML element. - * @param options Component options. - * @param classDef Class definition. - */ - protected static init>(el: I, options: O, classDef: ComponentType): C; - /** - * Initializes component instances. - * @param els HTML elements. - * @param options Component options. - * @param classDef Class definition. - */ - protected static init>(els: InitElements, options: Partial, classDef: ComponentType): C[]; - /** - * Initializes component instances. - * @param els HTML elements. - * @param options Component options. - * @param classDef Class definition. - */ - protected static init>(els: I | InitElements, options: Partial, classDef: ComponentType): C | C[]; - /** - * @returns default options for component instance. - */ - static get defaults(): BaseOptions$1; - /** - * Retrieves component instance for the given element. - * @param el Associated HTML Element. - */ - static getInstance(el: HTMLElement): Component; - /** - * Destroy plugin instance and teardown. - */ - destroy(): void; -} - -interface DropdownOptions extends BaseOptions$1 { - /** - * Defines the edge the menu is aligned to. - * @default 'left' - */ - alignment: 'left' | 'right'; - /** - * If true, automatically focus dropdown el for keyboard. - * @default true - */ - autoFocus: boolean; - /** - * If true, constrainWidth to the size of the dropdown activator. - * @default true - */ - constrainWidth: boolean; - /** - * Provide an element that will be the bounding container of the dropdown. - * @default null - */ - container: Element; - /** - * If false, the dropdown will show below the trigger. - * @default true - */ - coverTrigger: boolean; - /** - * If true, close dropdown on item click. - * @default true - */ - closeOnClick: boolean; - /** - * If true, the dropdown will open on hover. - * @default false - */ - hover: boolean; - /** - * The duration of the transition enter in milliseconds. - * @default 150 - */ - inDuration: number; - /** - * The duration of the transition out in milliseconds. - * @default 250 - */ - outDuration: number; - /** - * Function called when dropdown starts entering. - * @default null - */ - onOpenStart: (el: HTMLElement) => void; - /** - * Function called when dropdown finishes entering. - * @default null - */ - onOpenEnd: (el: HTMLElement) => void; - /** - * Function called when dropdown starts exiting. - * @default null - */ - onCloseStart: (el: HTMLElement) => void; - /** - * Function called when dropdown finishes exiting. - * @default null - */ - onCloseEnd: (el: HTMLElement) => void; - /** - * Function called when item is clicked. - * @default null - */ - onItemClick: (el: HTMLLIElement) => void; -} -declare class Dropdown extends Component implements Openable { - static _dropdowns: Dropdown[]; - /** ID of the dropdown element. */ - id: string; - /** The DOM element of the dropdown. */ - dropdownEl: HTMLElement; - /** If the dropdown is open. */ - isOpen: boolean; - /** If the dropdown content is scrollable. */ - isScrollable: boolean; - isTouchMoving: boolean; - /** The index of the item focused. */ - focusedIndex: number; - filterQuery: string[]; - filterTimeout: NodeJS.Timeout | number; - constructor(el: HTMLElement, options: Partial); - static get defaults(): DropdownOptions; - /** - * Initializes instance of Dropdown. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Dropdown; - /** - * Initializes instances of Dropdown. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Dropdown[]; - static getInstance(el: HTMLElement): Dropdown; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _setupTemporaryEventHandlers(): void; - _removeTemporaryEventHandlers(): void; - _handleClick: (e: MouseEvent) => void; - _handleMouseEnter: () => void; - _handleMouseLeave: (e: MouseEvent) => void; - _handleDocumentClick: (e: MouseEvent) => void; - _handleTriggerKeydown: (e: KeyboardEvent) => void; - _handleDocumentTouchmove: (e: TouchEvent) => void; - _handleDropdownClick: (e: MouseEvent) => void; - _handleDropdownKeydown: (e: KeyboardEvent) => void; - _handleWindowResize: () => void; - _resetFilterQuery: () => void; - _resetDropdownStyles(): void; - _resetDropdownPositioningStyles(): void; - _moveDropdownToElement(containerEl?: HTMLElement): void; - _makeDropdownFocusable(): void; - _focusFocusedItem(): void; - _getDropdownPosition(closestOverflowParent: HTMLElement): { - x: number; - y: number; - verticalAlignment: string; - horizontalAlignment: "left" | "right"; - height: number; - width: number; - }; - _animateIn(): void; - _animateOut(): void; - private _getClosestAncestor; - _placeDropdown(): void; - /** - * Open dropdown. - */ - open: () => void; - /** - * Close dropdown. - */ - close: () => void; - /** - * While dropdown is open, you can recalculate its dimensions if its contents have changed. - */ - recalculateDimensions: () => void; -} - -interface AutocompleteData { - /** - * A primitive value that can be converted to string. - * If "text" is not provided, it will also be used as "option text" as well - */ - id: string | number; - /** - * This optional attribute is used as "display value" for the current entry. - * When provided, it will also be taken into consideration by the standard search function. - */ - text?: string; - /** - * This optional attribute is used to provide a valid image URL to the current option. - */ - image?: string; - /** - * Optional attributes which describes the option. - */ - description?: string; -} -interface AutocompleteOptions extends BaseOptions$1 { - /** - * Data object defining autocomplete options with - * optional icon strings. - */ - data: AutocompleteData[]; - /** - * Flag which can be set if multiple values can be selected. The Result will be an Array. - * @default false - */ - isMultiSelect: boolean; - /** - * Callback for when autocompleted. - */ - onAutocomplete: (entries: AutocompleteData[]) => void; - /** - * Minimum number of characters before autocomplete starts. - * @default 1 - */ - minLength: number; - /** - * The height of the Menu which can be set via css-property. - * @default '300px' - */ - maxDropDownHeight: string; - /** - * Function is called when the input text is altered and data can also be loaded asynchronously. - * If the results are collected the items in the list can be updated via the function setMenuItems(collectedItems). - * @param text Searched text. - * @param autocomplete Current autocomplete instance. - */ - onSearch: (text: string, autocomplete: Autocomplete) => void; - /** - * If true will render the key from each item directly as HTML. - * User input MUST be properly sanitized first. - * @default false - */ - allowUnsafeHTML: boolean; - /** - * Pass options object to select dropdown initialization. - * @default {} - */ - dropdownOptions: Partial; - /** - * Predefined selected values - */ - selected: number[] | string[]; -} -declare class Autocomplete extends Component { - el: HTMLInputElement; - /** If the autocomplete is open. */ - isOpen: boolean; - /** Number of matching autocomplete options. */ - count: number; - /** Index of the current selected option. */ - activeIndex: number; - private oldVal; - private $active; - private _mousedown; - container: HTMLElement; - /** Instance of the dropdown plugin for this autocomplete. */ - dropdown: Dropdown; - static _keydown: boolean; - selectedValues: AutocompleteData[]; - menuItems: AutocompleteData[]; - data: AutocompleteData[]; - constructor(el: HTMLInputElement, options: Partial); - static get defaults(): AutocompleteOptions; - /** - * Initializes instance of Autocomplete. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLInputElement, options?: Partial): Autocomplete; - /** - * Initializes instances of Autocomplete. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Autocomplete[]; - static getInstance(el: HTMLElement): Autocomplete; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _setupDropdown(): void; - _removeDropdown(): void; - _handleInputBlur: () => void; - _handleInputKeyup: (e: KeyboardEvent) => void; - _handleInputFocus: () => void; - _inputChangeDetection: (value: string) => void; - _handleInputKeydown: (e: KeyboardEvent) => void; - _handleInputClick: () => void; - _handleContainerMousedownAndTouchstart: () => void; - _handleContainerMouseupAndTouchend: () => void; - _resetCurrentElementPosition(): void; - _resetAutocomplete(): void; - _highlightPartialText(input: string, label: string): string[]; - _createDropdownItem(entry: AutocompleteData): HTMLLIElement; - _renderDropdown(): void; - _setStatusLoading(): void; - _updateSelectedInfo(): void; - _refreshInputText(): void; - _triggerChanged(): void; - /** - * Show autocomplete. - */ - open: () => void; - /** - * Hide autocomplete. - */ - close: () => void; - /** - * Updates the visible or selectable items shown in the menu. - * @param menuItems Items to be available. - * @param selected Selected item ids - * @param open Option to conditionally open dropdown - * @param initial Condition to set initial data - */ - setMenuItems(menuItems: AutocompleteData[], selected?: number[] | string[], open?: boolean, initial?: boolean): void; - /** - * Sets selected values. - * @deprecated @see https://github.com/materializecss/materialize/issues/552 - * @param entries - */ - setValues(entries: AutocompleteData[]): void; - /** - * Select a specific autocomplete option via id-property. - * @param id The id of a data-entry. - */ - selectOption(id: number | string): void; - selectOptions(ids: []): void; -} - -interface FloatingActionButtonOptions extends BaseOptions$1 { - /** - * Direction FAB menu opens. - * @default "top" - */ - direction: 'top' | 'right' | 'bottom' | 'left'; - /** - * true: FAB menu appears on hover, false: FAB menu appears on click. - * @default true - */ - hoverEnabled: boolean; - /** - * Enable transit the FAB into a toolbar on click. - * @default false - */ - toolbarEnabled: boolean; -} -declare class FloatingActionButton extends Component implements Openable { - #private; - /** - * Describes open/close state of FAB. - */ - isOpen: boolean; - offsetY: number; - offsetX: number; - btnBottom: number; - btnLeft: number; - btnWidth: number; - constructor(el: HTMLElement, options: Partial); - static get defaults(): FloatingActionButtonOptions; - /** - * Initializes instance of FloatingActionButton. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): FloatingActionButton; - /** - * Initializes instances of FloatingActionButton. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): FloatingActionButton[]; - static getInstance(el: HTMLElement): FloatingActionButton; - destroy(): void; - /** - * Open FAB. - */ - open: () => void; - /** - * Close FAB. - */ - close: () => void; -} - -interface CardsOptions extends BaseOptions$1 { - onOpen: (el: Element) => void; - onClose: (el: Element) => void; - inDuration: number; - outDuration: number; -} -declare class Cards extends Component implements Openable { - #private; - isOpen: boolean; - constructor(el: HTMLElement, options: Partial); - static get defaults(): CardsOptions; - /** - * Initializes instance of Cards. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Cards; - /** - * Initializes instances of Cards. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Cards[]; - static getInstance(el: HTMLElement): Cards; - /** - * {@inheritDoc} - */ - destroy(): void; - /** - * Show card reveal. - */ - open: () => void; - /** - * Hide card reveal. - */ - close: () => void; - static Init(): void; -} - -interface CarouselOptions extends BaseOptions$1 { - /** - * Transition duration in milliseconds. - * @default 200 - */ - duration: number; - /** - * Perspective zoom. If 0, all items are the same size. - * @default -100 - */ - dist: number; - /** - * Set the spacing of the center item. - * @default 0 - */ - shift: number; - /** - * Set the padding between non center items. - * @default 0 - */ - padding: number; - /** - * Set the number of visible items. - * @default 5 - */ - numVisible: number; - /** - * Make the carousel a full width slider like the second example. - * @default false - */ - fullWidth: boolean; - /** - * Set to true to show indicators. - * @default false - */ - indicators: boolean; - /** - * Don't wrap around and cycle through items. - * @default false - */ - noWrap: boolean; - /** - * Callback for when a new slide is cycled to. - * @default null - */ - onCycleTo: (current: Element, dragged: boolean) => void; -} -declare class Carousel extends Component { - hasMultipleSlides: boolean; - showIndicators: boolean; - noWrap: boolean; - /** If the carousel is being clicked or tapped. */ - pressed: boolean; - /** If the carousel is currently being dragged. */ - dragged: boolean; - offset: number; - target: number; - images: HTMLElement[]; - itemWidth: number; - itemHeight: number; - dim: number; - _indicators: HTMLUListElement; - count: number; - xform: string; - verticalDragged: boolean; - reference: number; - referenceY: number; - velocity: number; - frame: number; - timestamp: number; - ticker: string | number | NodeJS.Timeout; - amplitude: number; - /** The index of the center carousel item. */ - center: number; - imageHeight: number; - scrollingTimeout: number | NodeJS.Timeout; - oneTimeCallback: (current: Element, dragged: boolean) => void | null; - constructor(el: HTMLElement, options: Partial); - static get defaults(): CarouselOptions; - /** - * Initializes instance of Carousel. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Carousel; - /** - * Initializes instances of Carousel. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Carousel[]; - static getInstance(el: HTMLElement): Carousel; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleThrottledResize: () => void; - _handleCarouselTap: (e: MouseEvent | TouchEvent) => void; - _handleCarouselDrag: (e: MouseEvent | TouchEvent) => boolean; - _handleCarouselRelease: (e: MouseEvent | TouchEvent) => boolean; - _handleCarouselClick: (e: MouseEvent | TouchEvent) => boolean; - _handleIndicatorClick: (e: Event) => void; - _handleIndicatorKeyPress: (e: KeyboardEvent) => void; - _handleIndicatorInteraction: (e: Event) => void; - _handleResize: () => void; - _setCarouselHeight(imageOnly?: boolean): void; - _xpos(e: MouseEvent | TouchEvent): number; - _ypos(e: MouseEvent | TouchEvent): number; - _wrap(x: number): any; - _track: () => void; - _autoScroll: () => void; - _scroll(x?: number): void; - _updateItemStyle(el: HTMLElement, opacity: number, zIndex: number, transform: string): void; - _cycleTo(n: number, callback?: CarouselOptions['onCycleTo']): void; - /** - * Move carousel to next slide or go forward a given amount of slides. - * @param n How many times the carousel slides. - */ - next(n?: number): void; - /** - * Move carousel to previous slide or go back a given amount of slides. - * @param n How many times the carousel slides. - */ - prev(n?: number): void; - /** - * Move carousel to nth slide. - * @param n Index of slide. - * @param callback "onCycleTo" optional callback. - */ - set(n: number, callback?: CarouselOptions['onCycleTo']): void; -} - -interface ChipData { - /** Unique identifier. */ - id: number | string; - /** Chip text. If not specified, "id" will be used. */ - text?: string; - /** Chip image (URL). */ - image?: string; -} -interface ChipsOptions extends BaseOptions$1 { - /** - * Set the chip data. - * @default [] - */ - data: ChipData[]; - /** - * Set first placeholder when there are no tags. - * @default "" - */ - placeholder: string; - /** - * Set second placeholder when adding additional tags. - * @default "" - */ - secondaryPlaceholder: string; - /** - * Set autocomplete options. - * @default {} - */ - autocompleteOptions: Partial; - /** - * Toggles abililty to add custom value not in autocomplete list. - * @default false - */ - autocompleteOnly: boolean; - /** - * Set chips limit. - * @default Infinity - */ - limit: number; - /** - * Specifies class to be used in "close" button (useful when working with Material Symbols icon set). - * @default 'material-icons' - */ - closeIconClass: string; - /** - * Specifies option to render user input field - * @default false; - */ - allowUserInput: boolean; - /** - * Callback for chip add. - * @default null - */ - onChipAdd: (element: HTMLElement, chip: HTMLElement) => void; - /** - * Callback for chip select. - * @default null - */ - onChipSelect: (element: HTMLElement, chip: HTMLElement) => void; - /** - * Callback for chip delete. - * @default null - */ - onChipDelete: (element: HTMLElement, chip: HTMLElement) => void; -} -declare class Chips extends Component { - #private; - /** Array of the current chips data. */ - chipsData: ChipData[]; - /** If the chips has autocomplete enabled. */ - hasAutocomplete: boolean; - /** Autocomplete instance, if any. */ - autocomplete: Autocomplete; - constructor(el: HTMLElement, options: Partial); - static get defaults(): ChipsOptions; - /** - * Initializes instance of Chips. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Chips; - /** - * Initializes instances of Chips. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Chips[]; - static getInstance(el: HTMLElement): Chips; - getData(): ChipData[]; - destroy(): void; - /** - * Add chip to input. - * @param chip Chip data object - */ - addChip(chip: ChipData): void; - /** - * Delete nth chip. - * @param chipIndex Index of chip - */ - deleteChip(chipIndex: number): void; - /** - * Select nth chip. - * @param chipIndex Index of chip - */ - selectChip(chipIndex: number): void; - static Init(): void; -} - -interface CollapsibleOptions extends BaseOptions$1 { - /** - * If accordion versus collapsible. - * @default true - */ - accordion: boolean; - /** - * Transition in duration in milliseconds. - * @default 300 - */ - inDuration: number; - /** - * Transition out duration in milliseconds. - * @default 300 - */ - outDuration: number; - /** - * Callback function called before collapsible is opened. - * @default null - */ - onOpenStart: (el: Element) => void; - /** - * Callback function called after collapsible is opened. - * @default null - */ - onOpenEnd: (el: Element) => void; - /** - * Callback function called before collapsible is closed. - * @default null - */ - onCloseStart: (el: Element) => void; - /** - * Callback function called after collapsible is closed. - * @default null - */ - onCloseEnd: (el: Element) => void; -} -declare class Collapsible extends Component { - private _headers; - constructor(el: HTMLElement, options: Partial); - static get defaults(): CollapsibleOptions; - /** - * Initializes instance of Collapsible. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Collapsible; - /** - * Initializes instances of Collapsible. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Collapsible[]; - static getInstance(el: HTMLElement): Collapsible; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleCollapsibleClick: (e: MouseEvent | KeyboardEvent) => void; - _handleCollapsibleKeydown: (e: KeyboardEvent) => void; - private _setExpanded; - _animateIn(index: number): void; - _animateOut(index: number): void; - /** - * Open collapsible section. - * @param n Nth section to open. - */ - open: (index: number) => void; - /** - * Close collapsible section. - * @param n Nth section to close. - */ - close: (index: number) => void; -} - -interface DateI18nOptions extends I18nOptions { - previousMonth: string; - nextMonth: string; - months: string[]; - monthsShort: string[]; - weekdays: string[]; - weekdaysShort: string[]; - weekdaysAbbrev: string[]; -} -interface DatepickerOptions extends BaseOptions$1 { - /** - * The date output format for the input field value - * or a function taking the date and outputting the - * formatted date string. - * @default 'mmm dd, yyyy' - */ - format: string | ((d: Date) => string); - /** - * Used to create date object from current input string. - * @default null - */ - parse: ((value: string, format: string) => Date) | null; - /** - * The initial condition if the datepicker is based on date range. - * @default false - */ - isDateRange: boolean; - /** - * The selector of the user specified date range end element - */ - dateRangeEndEl: string | null; - /** - * The initial condition if the datepicker is based on multiple date selection. - * @default false - */ - isMultipleSelection: boolean; - /** - * The initial date to view when first opened. - * @default null - */ - defaultDate: Date | null; - /** - * The initial end date to view when first opened. - * @default null - */ - defaultEndDate: Date | null; - /** - * Make the `defaultDate` the initial selected value. - * @default false - */ - setDefaultDate: boolean; - /** - * Make the `defaultEndDate` the initial selected value. - * @default false - */ - setDefaultEndDate: boolean; - /** - * Prevent selection of any date on the weekend. - * @default false - */ - disableWeekends: boolean; - /** - * Custom function to disable certain days. - * @default null - */ - disableDayFn: ((day: Date) => boolean) | null; - /** - * First day of week (0: Sunday, 1: Monday etc). - * @default 0 - */ - firstDay: number; - /** - * The earliest date that can be selected. - * @default null - */ - minDate: Date | null; - /** - * The latest date that can be selected. - * @default null - */ - maxDate: Date | null; - /** - * Number of years either side, or array of upper/lower range. - * @default 10 - */ - yearRange: number | number[]; - /** - * Sort year range in reverse order. - * @default false - */ - yearRangeReverse: boolean; - /** - * Changes Datepicker to RTL. - * @default false - */ - isRTL: boolean; - /** - * Show month after year in Datepicker title. - * @default false - */ - showMonthAfterYear: boolean; - /** - * Render days of the calendar grid that fall in the next - * or previous month. - * @default false - */ - showDaysInNextAndPreviousMonths: boolean; - /** - * Specify if the docked datepicker is in open state by default - */ - openByDefault: boolean; - /** - * Specify a DOM element OR selector for a DOM element to render - * the calendar in, by default it will be placed before the input. - * @default null - */ - container: HTMLElement | string | null; - /** - * Show the clear button in the datepicker. - * @default false - */ - showClearBtn: boolean; - /** - * Autosubmit calendar day select to input field - * @default false - */ - autoSubmit: true; - /** - * Internationalization options. - */ - i18n: Partial; - /** - * An array of string returned by `Date.toDateString()`, - * indicating there are events in the specified days. - * @default [] - */ - events: string[]; - /** - * Callback function when date is selected, - * first parameter is the newly selected date. - * @default null - */ - onSelect: ((selectedDate: Date) => void) | null; - /** - * Callback function when Datepicker is closed. - * @default null - */ - /** - * Callback function when Datepicker HTML is refreshed. - * @default null - */ - onDraw: (() => void) | null; - /** - * Callback function for interaction with input field. - * @default null - */ - onInputInteraction: (() => void) | null; - /** - * Callback function for interaction with confirm button. - * @default null - */ - onConfirm: (() => void) | null; - /** - * Callback function for interaction with close button. - * @default null - */ - onCancel: (() => void) | null; - /** Field used for internal calculations DO NOT CHANGE IT */ - minYear?: number; - /** Field used for internal calculations DO NOT CHANGE IT */ - maxYear?: number; - /** Field used for internal calculations DO NOT CHANGE IT */ - minMonth?: number; - /** Field used for internal calculations DO NOT CHANGE IT */ - maxMonth?: number; - /** Field used for internal calculations DO NOT CHANGE IT */ - startRange?: Date; - /** Field used for internal calculations DO NOT CHANGE IT */ - endRange?: Date; - /** - * Display plugin - */ - displayPlugin: string; - /** - * Configurable display plugin options - */ - displayPluginOptions: object; -} -declare class Datepicker extends Component { - el: HTMLInputElement; - id: string; - multiple: boolean; - calendarEl: HTMLElement; - /** CLEAR button instance. */ - /** DONE button instance */ - containerEl: HTMLElement; - yearTextEl: HTMLElement; - dateTextEl: HTMLElement; - endDateEl: HTMLInputElement; - dateEls: HTMLInputElement[]; - /** The selected Date. */ - date: Date; - endDate: null | Date; - dates: Date[]; - formats: object; - calendars: [{ - month: number; - year: number; - }]; - private _y; - private _m; - private displayPlugin; - private footer; - static _template: string; - constructor(el: HTMLInputElement, options: Partial); - static get defaults(): DatepickerOptions; - /** - * Initializes instance of Datepicker. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLInputElement, options?: Partial): Datepicker; - /** - * Initializes instances of Datepicker. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Datepicker[]; - static _isDate(obj: any): boolean; - static _isWeekend(date: any): boolean; - /** - * @deprecated as this function has no effect without any return statement or global parameter setter. - */ - static _setToStartOfDay(date: any): void; - static _getDaysInMonth(year: any, month: any): number; - static _isLeapYear(year: any): boolean; - static _compareDates(a: any, b: any): boolean; - static _compareWithinRange(day: Date, date: Date, dateEnd: Date): boolean; - static _comparePastDate(a: Date, b: Date): boolean; - static getInstance(el: HTMLElement): Datepicker; - destroy(): void; - destroySelects(): void; - _insertHTMLIntoDOM(): void; - /** - * Renders the date input format - */ - _renderDateInputFormat(el: HTMLInputElement): void; - /** - * Gets a string representation of the given date. - */ - toString(date?: Date, format?: string | ((d: Date) => string)): string; - /** - * Returns the formatted date. - */ - formatDate(date: Date, format: string): string; - /** - * Sets date from input field. - */ - setDateFromInput(el: HTMLInputElement): void; - /** - * Set a date on the datepicker. - * @param date Date to set on the datepicker. - * @param preventOnSelect Undocumented as of 5 March 2018. - * @param isEndDate - * @param fromUserInput - */ - setDate(date?: Date, preventOnSelect?: boolean, isEndDate?: boolean, fromUserInput?: boolean): void; - validateDate(date: Date): void | Date; - /** - * Set a single date on the datepicker. - * @param date Date to set on the datepicker. - * @param isEndDate - */ - setSingleDate(date: Date, isEndDate: boolean): void; - /** - * Set a multi date on the datepicker. - * @param date Date to set on the datepicker. - */ - setMultiDate(date: Date): void; - /** - * Sets the data-date attribute on the date input field - */ - setDataDate(el: any, date: any): void; - /** - * Sets dates on the input values. - */ - setInputValues(): void; - setMultipleSelectionInputValues(): void; - /** - * Sets given date as the input value on the given element. - */ - setInputValue(el: any, date: any): void; - /** - * Display plugin setup. - */ - _setupDisplayPlugin(): void; - /** - * Renders the date in the modal head section. - */ - _renderDateDisplay(date: Date, endDate?: Date): void; - /** - * Change date view to a specific date on the datepicker. - * @param date Date to show on the datepicker. - */ - gotoDate(date: Date): void; - adjustCalendars(): void; - adjustCalendar(calendar: any): any; - nextMonth(): void; - prevMonth(): void; - render(year: any, month: any, randId: any): string; - renderDay(opts: any): string; - renderRow(days: any, isRTL: any, isRowSelected: any): string; - renderTable(opts: any, data: any, randId: any): string; - renderHead(opts: any): string; - renderBody(rows: any): string; - renderTitle(instance: any, c: any, year: any, month: any, refYear: any, randId: any): string; - draw(): void; - _setupEventHandlers(): void; - _setupVariables(): void; - _pickerSetup(): void; - _removeEventHandlers(): void; - _handleInputClick: (e: any) => void; - _handleInputKeydown: (e: KeyboardEvent) => void; - _handleCalendarClick: (e: any) => void; - _handleDateRangeCalendarClick: (date: Date) => void; - _handleClearClick: () => void; - _clearDates: () => void; - _handleMonthChange: (e: any) => void; - _handleYearChange: (e: any) => void; - gotoMonth(month: any): void; - gotoYear(year: any): void; - _handleInputChange: (e: Event) => void; - renderDayName(opts: any, day: any, abbr?: boolean): any; - createDateInput(): HTMLInputElement; - _finishSelection: () => void; - _confirm: () => void; - _cancel: () => void; - open(): this; - close(): this; -} - -declare class Forms { - /** - * Checks if the label has validation and apply - * the correct class and styles - * @param textfield - */ - static validateField(textfield: HTMLInputElement): void; - /** - * Resizes the given TextArea after updating the - * value content dynamically. - * @param e EventTarget - */ - static textareaAutoResize(e: EventTarget): void; - static Init(): void; - static InitTextarea(textarea: HTMLTextAreaElement): void; - static InitFileInputPath(fileInput: HTMLInputElement): void; -} - -interface MaterialboxOptions extends BaseOptions$1 { - /** - * Transition in duration in milliseconds. - * @default 275 - */ - inDuration: number; - /** - * Transition out duration in milliseconds. - * @default 200 - */ - outDuration: number; - /** - * Callback function called before materialbox is opened. - * @default null - */ - onOpenStart: (el: Element) => void; - /** - * Callback function called after materialbox is opened. - * @default null - */ - onOpenEnd: (el: Element) => void; - /** - * Callback function called before materialbox is closed. - * @default null - */ - onCloseStart: (el: Element) => void; - /** - * Callback function called after materialbox is closed. - * @default null - */ - onCloseEnd: (el: Element) => void; -} -declare class Materialbox extends Component { - /** If the materialbox overlay is showing. */ - overlayActive: boolean; - /** If the materialbox is no longer being animated. */ - doneAnimating: boolean; - /** Caption, if specified. */ - caption: string; - /** Original width of image. */ - originalWidth: number; - /** Original height of image. */ - originalHeight: number; - private originInlineStyles; - private placeholder; - private _changedAncestorList; - private newHeight; - private newWidth; - private windowWidth; - private windowHeight; - private attrWidth; - private attrHeight; - private _overlay; - private _photoCaption; - constructor(el: HTMLElement, options: Partial); - static get defaults(): MaterialboxOptions; - /** - * Initializes instance of MaterialBox. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Materialbox; - /** - * Initializes instances of MaterialBox. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Materialbox[]; - static getInstance(el: HTMLElement): Materialbox; - destroy(): void; - private _setupEventHandlers; - private _removeEventHandlers; - private _handleMaterialboxClick; - private _handleMaterialboxKeypress; - private _handleMaterialboxToggle; - private _handleWindowScroll; - private _handleWindowResize; - private _handleWindowEscape; - private _makeAncestorsOverflowVisible; - private _offset; - private _updateVars; - private _animateImageIn; - private _animateImageOut; - private _addCaption; - private _removeCaption; - private _addOverlay; - private _removeOverlay; - /** - * Open materialbox. - */ - open: () => void; - /** - * Close materialbox. - */ - close: () => void; -} - -interface ModalOptions extends BaseOptions$1 { - opacity: number; - inDuration: number; - outDuration: number; - preventScrolling: boolean; - onOpenStart: (this: Modal, el: HTMLElement) => void; - onOpenEnd: (this: Modal, el: HTMLElement) => void; - onCloseStart: (el: HTMLElement) => void; - onCloseEnd: (el: HTMLElement) => void; - dismissible: boolean; - startingTop: string; - endingTop: string; -} -declare class Modal extends Component { - #private; - constructor(el: HTMLElement, options: Partial); - static get defaults(): { - opacity: number; - inDuration: number; - outDuration: number; - onOpenStart: any; - onOpenEnd: any; - onCloseStart: any; - onCloseEnd: any; - preventScrolling: boolean; - dismissible: boolean; - startingTop: string; - endingTop: string; - }; - static init(el: HTMLElement, options?: Partial): Modal; - static init(els: InitElements, options?: Partial): Modal[]; - static getInstance(el: HTMLElement): Modal; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleTriggerClick(): void; - _handleOverlayClick(): void; - _handleModalCloseClick(): void; - _handleKeydown(): void; - _handleFocus(): void; - open(): this; - close(): this; - static create(config: any): string | HTMLDialogElement; -} - -interface FormSelectOptions extends BaseOptions$1 { - /** - * Classes to be added to the select wrapper element. - * @default "" - */ - classes: string; - /** - * Pass options object to select dropdown initialization. - * @default {} - */ - dropdownOptions: Partial; -} -type ValueStruct = { - el: HTMLOptionElement; - optionEl: HTMLElement; -}; -declare class FormSelect extends Component { - el: HTMLSelectElement; - /** If this is a multiple select. */ - isMultiple: boolean; - /** - * Label associated with the current select element. - * Is "null", if not detected. - */ - labelEl: HTMLLabelElement; - /** Dropdown UL element. */ - dropdownOptions: HTMLUListElement; - /** Text input that shows current selected option. */ - input: HTMLInputElement; - /** Instance of the dropdown plugin for this select. */ - dropdown: Dropdown; - /** The select wrapper element. */ - wrapper: HTMLDivElement; - selectOptions: (HTMLOptionElement | HTMLOptGroupElement)[]; - private _values; - nativeTabIndex: number; - constructor(el: HTMLSelectElement, options: FormSelectOptions); - static get defaults(): FormSelectOptions; - /** - * Initializes instance of FormSelect. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLSelectElement, options?: Partial): FormSelect; - /** - * Initializes instances of FormSelect. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): FormSelect[]; - static getInstance(el: HTMLElement): FormSelect; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleSelectChange: () => void; - _handleOptionClick: (e: MouseEvent | KeyboardEvent) => void; - _arraysEqual(a: T[], b: (E | T)[]): boolean; - _selectOptionElement(virtualOption: HTMLElement): void; - _handleInputClick: () => void; - _setupDropdown(): void; - _addOptionToValues(realOption: HTMLOptionElement, virtualOption: HTMLElement): void; - _removeDropdown(): void; - _createAndAppendOptionWithIcon(realOption: HTMLOptionElement | HTMLOptGroupElement, type: string): HTMLLIElement; - _selectValue(value: ValueStruct): void; - _deselectValue(value: ValueStruct): void; - _deselectAll(): void; - _isValueSelected(value: ValueStruct): boolean; - _toggleEntryFromArray(value: ValueStruct): void; - _getSelectedOptions(): HTMLOptionElement[]; - _setValueToInput(): void; - _setSelectedStates(): void; - _activateOption(ul: HTMLElement, li: HTMLElement): void; - getSelectedValues(): string[]; -} - -interface SidenavOptions extends BaseOptions$1 { - /** - * Side of screen on which Sidenav appears. - * @default 'left' - */ - edge: 'left' | 'right'; - /** - * Allow swipe gestures to open/close Sidenav. - * @default true - */ - draggable: boolean; - /** - * Width of the area where you can start dragging. - * @default '10px' - */ - dragTargetWidth: string; - /** - * Length in ms of enter transition. - * @default 250 - */ - inDuration: number; - /** - * Length in ms of exit transition. - * @default 200 - */ - outDuration: number; - /** - * Prevent page from scrolling while sidenav is open. - * @default true - */ - preventScrolling: boolean; - /** - * Function called when sidenav starts entering. - */ - onOpenStart: (elem: HTMLElement) => void; - /** - * Function called when sidenav finishes entering. - */ - onOpenEnd: (elem: HTMLElement) => void; - /** - * Function called when sidenav starts exiting. - */ - onCloseStart: (elem: HTMLElement) => void; - /** - * Function called when sidenav finishes exiting. - */ - onCloseEnd: (elem: HTMLElement) => void; -} -declare class Sidenav extends Component implements Openable { - id: string; - /** Describes open/close state of Sidenav. */ - isOpen: boolean; - /** Describes if sidenav is fixed. */ - isFixed: boolean; - /** Describes if Sidenav is being dragged. */ - isDragged: boolean; - lastWindowWidth: number; - lastWindowHeight: number; - static _sidenavs: Sidenav[]; - private _overlay; - dragTarget: Element; - private _startingXpos; - private _xPos; - private _time; - private _width; - private _initialScrollTop; - private _verticallyScrolling; - private deltaX; - private velocityX; - private percentOpen; - constructor(el: HTMLElement, options: Partial); - static get defaults(): SidenavOptions; - /** - * Initializes instance of Sidenav. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Sidenav; - /** - * Initializes instances of Sidenav. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Sidenav[]; - static getInstance(el: HTMLElement): Sidenav; - destroy(): void; - private _createOverlay; - private _setupEventHandlers; - private _removeEventHandlers; - private _handleTriggerClick; - private _startDrag; - private _dragMoveUpdate; - private _handleDragTargetDrag; - private _handleDragTargetRelease; - private _handleCloseDrag; - private _calculateDelta; - private _handleCloseRelease; - private _handleCloseTriggerClick; - private _handleWindowResize; - private _setupClasses; - private _removeClasses; - private _setupFixed; - private _isDraggable; - private _isCurrentlyFixed; - private _createDragTarget; - private _preventBodyScrolling; - private _enableBodyScrolling; - /** - * Opens Sidenav. - */ - open: () => void; - /** - * Closes Sidenav. - */ - close: () => void; - private _animateIn; - private _animateOut; - private _animateSidenavIn; - private _animateSidenavOut; - private _animateOverlayIn; - private _animateOverlayOut; - private _setAriaHidden; - private _setTabIndex; -} - -interface SliderOptions extends BaseOptions$1 { - /** - * Set to false to hide slide indicators. - * @default true - */ - indicators: boolean; - /** - * Set height of slider. - * @default 400 - */ - height: number; - /** - * Set the duration of the transition animation in ms. - * @default 500 - */ - duration: number; - /** - * Set the duration between transitions in ms. - * @default 6000 - */ - interval: number; - /** - * If slider should pause when keyboard focus is received. - * @default true - */ - pauseOnFocus: boolean; - /** - * If slider should pause when is hovered by a pointer. - * @default true - */ - pauseOnHover: boolean; - /** - * Optional function used to generate ARIA label to indicators (for accessibility purposes). - * @param index Current index, starting from "1". - * @param current A which indicates whether it is the current element or not - * @returns a string to be used as label indicator. - * @default null - */ - indicatorLabelFunc: (index: number, current: boolean) => string; -} -declare class Slider extends Component { - /** Index of current slide. */ - activeIndex: number; - interval: string | number | NodeJS.Timeout; - eventPause: boolean; - _slider: HTMLUListElement; - _slides: HTMLLIElement[]; - _activeSlide: HTMLLIElement; - _indicators: HTMLLIElement[]; - _hovered: boolean; - _focused: boolean; - _focusCurrent: boolean; - _sliderId: string; - constructor(el: HTMLElement, options: Partial); - static get defaults(): SliderOptions; - /** - * Initializes instance of Slider. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Slider; - /** - * Initializes instances of Slider. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Slider[]; - static getInstance(el: HTMLElement): Slider; - destroy(): void; - private _setupEventHandlers; - private _removeEventHandlers; - private _handleIndicatorClick; - private _handleAutoPauseHover; - private _handleAutoPauseFocus; - private _handleAutoStartHover; - private _handleAutoStartFocus; - private _handleInterval; - private _animateSlide; - private _setSliderHeight; - private _setupIndicators; - private _removeIndicators; - set(index: number): void; - _pause(fromEvent: boolean): void; - /** - * Pause slider autoslide. - */ - pause: () => void; - /** - * Start slider autoslide. - */ - start: () => void; - /** - * Move to next slider. - */ - next: () => void; - /** - * Move to prev slider. - */ - prev: () => void; -} - -interface TabsOptions extends BaseOptions$1 { - /** - * Transition duration in milliseconds. - * @default 300 - */ - duration: number; - /** - * Callback for when a new tab content is shown. - * @default null - */ - onShow: (newContent: Element) => void; - /** - * Set to true to enable swipeable tabs. - * This also uses the responsiveThreshold option. - * @default false - */ - swipeable: boolean; - /** - * The maximum width of the screen, in pixels, - * where the swipeable functionality initializes. - * @default infinity - */ - responsiveThreshold: number; -} -declare class Tabs extends Component { - _tabLinks: NodeListOf; - _index: number; - _indicator: HTMLLIElement; - _tabWidth: number; - _tabsWidth: number; - _tabsCarousel: Carousel; - _activeTabLink: HTMLAnchorElement; - _content: HTMLElement; - constructor(el: HTMLElement, options: Partial); - static get defaults(): TabsOptions; - /** - * Initializes instance of Tabs. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Tabs; - /** - * Initializes instances of Tabs. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Tabs[]; - static getInstance(el: HTMLElement): Tabs; - destroy(): void; - /** - * The index of tab that is currently shown. - */ - get index(): number; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleWindowResize: () => void; - _handleTabClick: (e: MouseEvent) => void; - _createIndicator(): void; - _setupActiveTabLink(): void; - _setupSwipeableTabs(): void; - _teardownSwipeableTabs(): void; - _setupNormalTabs(): void; - _teardownNormalTabs(): void; - _setTabsAndTabWidth(): void; - _calcRightPos(el: HTMLElement): number; - _calcLeftPos(el: HTMLElement): number; - /** - * Recalculate tab indicator position. This is useful when - * the indicator position is not correct. - */ - updateTabIndicator(): void; - _animateIndicator(prevIndex: number): void; - /** - * Show tab content that corresponds to the tab with the id. - * @param tabId The id of the tab that you want to switch to. - */ - select(tabId: string): void; -} - -type Views = 'hours' | 'minutes'; -interface TimepickerOptions extends BaseOptions$1 { - /** - * Dial radius. - * @default 135 - */ - dialRadius: number; - /** - * Outer radius. - * @default 105 - */ - outerRadius: number; - /** - * Inner radius. - * @default 70 - */ - innerRadius: number; - /** - * Tick radius. - * @default 20 - */ - tickRadius: number; - /** - * Duration of the transition from/to the hours/minutes view. - * @default 350 - */ - duration: number; - /** - * Specify a DOM element OR selector for a DOM element to render - * the time picker in, by default it will be placed before the input. - * @default null - */ - container: HTMLElement | string | null; - /** - * Show the clear button in the Timepicker. - * @default false - */ - showClearBtn: boolean; - /** - * Autosubmit timepicker selection to input field - * @default true - */ - autoSubmit: true; - /** - * Default time to set on the timepicker 'now' or '13:14'. - * @default 'now'; - */ - defaultTime: string; - /** - * Millisecond offset from the defaultTime. - * @default 0 - */ - fromNow: number; - /** - * Internationalization options. - */ - i18n: Partial; - /** - * Use 12 hour AM/PM clock instead of 24 hour clock. - * @default true - */ - twelveHour: boolean; - /** - * Vibrate device when dragging clock hand. - * @default true - */ - vibrate: boolean; - /** - * Callback function when a time is selected. - * @default null - */ - onSelect: (hour: number, minute: number) => void; - /** - * Callback function for interaction with input field. - * @default null - */ - onInputInteraction: (() => void) | null; - /** - * Callback function for done. - * @default null - */ - onDone: (() => void) | null; - /** - * Callback function for cancel. - * @default null - */ - onCancel: (() => void) | null; - /** - * Display plugin - */ - displayPlugin: string; - /** - * Configurable display plugin options - */ - displayPluginOptions: object; -} -type Point = { - x: number; - y: number; -}; -declare class Timepicker extends Component { - el: HTMLInputElement; - id: string; - containerEl: HTMLElement; - plate: HTMLElement; - digitalClock: HTMLElement; - inputHours: HTMLInputElement; - inputMinutes: HTMLInputElement; - x0: number; - y0: number; - moved: boolean; - dx: number; - dy: number; - /** - * Current view on the timepicker. - * @default 'hours' - */ - currentView: Views; - hand: SVGElement; - minutesView: HTMLElement; - hours: number; - minutes: number; - /** The selected time. */ - time: string; - /** - * If the time is AM or PM on twelve-hour clock. - * @default 'PM' - */ - amOrPm: 'AM' | 'PM'; - static _template: any; - /** Vibrate device when dragging clock hand. */ - vibrate: 'vibrate' | 'webkitVibrate' | null; - _canvas: HTMLElement; - hoursView: HTMLElement; - spanAmPm: HTMLSpanElement; - footer: HTMLElement; - private _amBtn; - private _pmBtn; - bg: Element; - bearing: Element; - g: Element; - toggleViewTimer: string | number | NodeJS.Timeout; - vibrateTimer: NodeJS.Timeout | number; - private displayPlugin; - constructor(el: HTMLInputElement, options: Partial); - static get defaults(): TimepickerOptions; - /** - * Initializes instance of Timepicker. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLInputElement, options?: Partial): Timepicker; - /** - * Initializes instances of Timepicker. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Timepicker[]; - static _addLeadingZero(num: number): string; - static _createSVGEl(name: string): SVGElement; - static _Pos(e: TouchEvent | MouseEvent): Point; - static getInstance(el: HTMLElement): Timepicker; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleInputClick: () => void; - _handleInputKeydown: (e: KeyboardEvent) => void; - _handleTimeInputEnterKey: (e: KeyboardEvent) => void; - _handleClockClickStart: (e: any) => void; - _handleDocumentClickMove: (e: any) => void; - _handleDocumentClickEnd: (e: any) => void; - _insertHTMLIntoDOM(): void; - _setupVariables(): void; - _pickerSetup(): void; - private _setupDisplayPlugin; - _clockSetup(): void; - _buildSVGClock(): void; - _buildHoursView(): void; - _buildHoursTick(i: number, radian: number, radius: number): void; - _buildMinutesView(): void; - _handleAmPmClick: (e: MouseEvent) => void; - _handleAmPmKeypress: (e: KeyboardEvent) => void; - _handleAmPmInteraction: (e: HTMLElement) => void; - _updateAmPmView(): void; - _updateTimeFromInput(): void; - /** - * Show hours or minutes view on timepicker. - * @param view The name of the view you want to switch to, 'hours' or 'minutes'. - * @param delay - */ - showView: (view: Views, delay?: number) => void; - resetClock(delay: any): void; - _inputFromTextField: () => void; - drawClockFromTimeInput(value: any, isHours: any): void; - setHand(x: any, y: any, roundBy5?: boolean): void; - setClockAttributes(radian: number, radius: number): void; - formatHours(): void; - formatMinutes(): void; - setHoursDefault(): void; - done: (clearValue?: any) => void; - confirm: () => void; - cancel: () => void; - clear: () => void; - open(): this; - close(): this; -} - -interface ToastOptions extends BaseOptions$1 { - /** - * The content of the Toast. - * @default "" - */ - text: string; - /** - * Element Id for the tooltip. - * @default "" - */ - toastId?: string; - /** - * Length in ms the Toast stays before dismissal. - * @default 4000 - */ - displayLength: number; - /** - * Transition in duration in milliseconds. - * @default 300 - */ - inDuration: number; - /** - * Transition out duration in milliseconds. - * @default 375 - */ - outDuration: number; - /** - * Classes to be added to the toast element. - * @default "" - */ - classes: string; - /** - * Callback function called when toast is dismissed. - * @default null - */ - completeCallback: () => void; - /** - * The percentage of the toast's width it takes fora drag - * to dismiss a Toast. - * @default 0.8 - */ - activationPercent: number; -} -declare class Toast { - /** The toast element. */ - el: HTMLElement; - /** - * The remaining amount of time in ms that the toast - * will stay before dismissal. - */ - timeRemaining: number; - /** - * Describes the current pan state of the Toast. - */ - panning: boolean; - options: ToastOptions; - message: string; - counterInterval: NodeJS.Timeout | number; - wasSwiped: boolean; - startingXPos: number; - xPos: number; - time: number; - deltaX: number; - velocityX: number; - static _toasts: Toast[]; - private static _container; - static _draggedToast: Toast; - constructor(options: Partial); - static get defaults(): ToastOptions; - static getInstance(el: HTMLElement): Toast; - static _createContainer(): void; - static _removeContainer(): void; - static _onDragStart(e: TouchEvent | MouseEvent): void; - static _onDragMove(e: TouchEvent | MouseEvent): void; - static _onDragEnd(): void; - static _xPos(e: TouchEvent | MouseEvent): number; - /** - * dismiss all toasts. - */ - static dismissAll(): void; - _createToast(): HTMLElement; - _animateIn(): void; - /** - * Create setInterval which automatically removes toast when timeRemaining >= 0 - * has been reached. - */ - _setTimer(): void; - /** - * Dismiss toast with animation. - */ - dismiss(): void; -} - -type TooltipPosition = 'top' | 'right' | 'bottom' | 'left'; -interface TooltipOptions extends BaseOptions$1 { - /** - * Delay time before tooltip disappears. - * @default 200 - */ - exitDelay: number; - /** - * Delay time before tooltip appears. - * @default 0 - */ - enterDelay: number; - /** - * Element Id for the tooltip. - * @default "" - */ - tooltipId?: string; - /** - * Text string for the tooltip. - * @default "" - */ - text: string; - /** - * Set distance tooltip appears away from its activator - * excluding transitionMovement. - * @default 5 - */ - margin: number; - /** - * Enter transition duration. - * @default 300 - */ - inDuration: number; - /** - * Opacity of the tooltip. - * @default 1 - */ - opacity: number; - /** - * Exit transition duration. - * @default 250 - */ - outDuration: number; - /** - * Set the direction of the tooltip. - * @default 'bottom' - */ - position: TooltipPosition; - /** - * Amount in px that the tooltip moves during its transition. - * @default 10 - */ - transitionMovement: number; -} -declare class Tooltip extends Component { - /** - * If tooltip is open. - */ - isOpen: boolean; - /** - * If tooltip is hovered. - */ - isHovered: boolean; - /** - * If tooltip is focused. - */ - isFocused: boolean; - tooltipEl: HTMLElement; - private _exitDelayTimeout; - private _enterDelayTimeout; - xMovement: number; - yMovement: number; - constructor(el: HTMLElement, options: Partial); - static get defaults(): TooltipOptions; - /** - * Initializes instance of Tooltip. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Tooltip; - /** - * Initializes instances of Tooltip. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Tooltip[]; - static getInstance(el: HTMLElement): Tooltip; - destroy(): void; - _appendTooltipEl(): void; - _setTooltipContent(tooltipContentEl: HTMLElement): void; - _updateTooltipContent(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - /** - * Show tooltip. - */ - open: (isManual: boolean) => void; - /** - * Hide tooltip. - */ - close: () => void; - _setExitDelayTimeout(): void; - _setEnterDelayTimeout(isManual: any): void; - _positionTooltip(): void; - _repositionWithinScreen(x: number, y: number, width: number, height: number): { - x: number; - y: number; - }; - _animateIn(): void; - _animateOut(): void; - _handleMouseEnter: () => void; - _handleMouseLeave: () => void; - _handleFocus: () => void; - _handleBlur: () => void; - _getAttributeOptions(): Partial; -} - -interface RangeOptions extends BaseOptions$1 { -} -declare class Range extends Component { - el: HTMLInputElement; - private _mousedown; - value: HTMLElement; - thumb: HTMLElement; - constructor(el: HTMLInputElement, options: Partial); - static get defaults(): RangeOptions; - /** - * Initializes instance of Range. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLInputElement, options?: Partial): Range; - /** - * Initializes instances of Range. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Range[]; - static getInstance(el: HTMLInputElement): Range; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleRangeChange: () => void; - _handleRangeMousedownTouchstart: (e: MouseEvent | TouchEvent) => void; - _handleRangeInputMousemoveTouchmove: () => void; - _handleRangeMouseupTouchend: () => void; - _handleRangeBlurMouseoutTouchleave: () => void; - _setupThumb(): void; - _removeThumb(): void; - _showRangeBubble(): void; - _calcRangeOffset(): number; - /** - * Initializes every range input in the current document. - */ - static Init(): void; -} - -interface TapTargetOptions extends BaseOptions$1 { - /** - * Callback function called when Tap Target is opened. - * @default null - */ - onOpen: (origin: HTMLElement) => void; - /** - * Callback function called when Tap Target is closed. - * @default null - */ - onClose: (origin: HTMLElement) => void; -} -declare class TapTarget extends Component implements Openable { - /** - * If the tap target is open. - */ - isOpen: boolean; - static _taptargets: TapTarget[]; - private wrapper; - private originEl; - private waveEl; - private contentEl; - constructor(el: HTMLElement, options: Partial); - static get defaults(): TapTargetOptions; - /** - * Initializes instance of TapTarget. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): TapTarget; - /** - * Initializes instances of TapTarget. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): TapTarget[]; - static getInstance(el: HTMLElement): TapTarget; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleThrottledResize: () => void; - _handleKeyboardInteraction: (e: KeyboardEvent) => void; - _handleTargetToggle: () => void; - _handleResize: () => void; - _handleDocumentClick: (e: MouseEvent | TouchEvent | KeyboardEvent) => void; - _setup(): void; - private _offset; - _calculatePositioning(): void; - /** - * Open Tap Target. - */ - open: () => void; - /** - * Close Tap Target. - */ - close: () => void; -} - -interface BaseOptions { -} -type InputElement = HTMLInputElement | HTMLTextAreaElement; -declare class CharacterCounter extends Component { - el: InputElement; - /** Stores the reference to the counter HTML element. */ - counterEl: HTMLSpanElement; - /** Specifies whether the input is valid or not. */ - isInvalid: boolean; - /** Specifies whether the input text has valid length or not. */ - isValidLength: boolean; - constructor(el: HTMLInputElement | HTMLTextAreaElement, options: Partial); - static get defaults(): BaseOptions; - /** - * Initializes instance of CharacterCounter. - * @param el HTML element. - * @param options Component options. - */ - static init(el: InputElement, options?: Partial): CharacterCounter; - /** - * Initializes instances of CharacterCounter. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): CharacterCounter[]; - static getInstance(el: InputElement): CharacterCounter; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _setupCounter(): void; - _removeCounter(): void; - updateCounter: () => void; - _validateInput(): void; -} - -declare class Edges { - top: boolean; - right: boolean; - bottom: boolean; - left: boolean; -} - -declare class Bounding { - left: number; - top: number; - width: number; - height: number; -} - -/** - * Class with utilitary functions for global usage. - */ -declare class Utils { - /** Specifies wether tab is pressed or not. */ - static tabPressed: boolean; - /** Specifies wether there is a key pressed. */ - static keyDown: boolean; - /** - * Key maps. - */ - static keys: { - TAB: string[]; - ENTER: string[]; - ESC: string[]; - BACKSPACE: string[]; - ARROW_UP: string[]; - ARROW_DOWN: string[]; - ARROW_LEFT: string[]; - ARROW_RIGHT: string[]; - DELETE: string[]; - }; - /** - * Detects when a key is pressed. - * @param e Event instance. - */ - static docHandleKeydown(e: KeyboardEvent): void; - /** - * Detects when a key is released. - * @param e Event instance. - */ - static docHandleKeyup(e: KeyboardEvent): void; - /** - * Detects when document is focused. - * @param e Event instance. - */ - static docHandleFocus(e: FocusEvent): void; - /** - * Detects when document is not focused. - * @param e Event instance. - */ - static docHandleBlur(e: FocusEvent): void; - /** - * Generates a unique string identifier. - */ - static guid(): string; - /** - * Checks for exceeded edges - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkWithinContainer(container: HTMLElement, bounding: Bounding, offset: number): Edges; - /** - * Checks if element can be aligned in multiple directions. - * @param el Element to be inspected. - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkPossibleAlignments(el: HTMLElement, container: HTMLElement, bounding: Bounding, offset: number): { - top: boolean; - right: boolean; - bottom: boolean; - left: boolean; - spaceOnTop: number; - spaceOnRight: number; - spaceOnBottom: number; - spaceOnLeft: number; - }; - /** - * Retrieves target element id from trigger. - * @param trigger Trigger element. - */ - static getIdFromTrigger(trigger: HTMLElement): string; - /** - * Retrieves document scroll postion from top. - */ - static getDocumentScrollTop(): number; - /** - * Retrieves document scroll postion from left. - */ - static getDocumentScrollLeft(): number; - /** - * Fires the given function after a certain ammount of time. - * @param func Function to be fired. - * @param wait Wait time. - * @param options Additional options. - */ - static throttle(func: (Function: object) => void, wait: number, options?: Partial<{ - leading: boolean; - trailing: boolean; - }>): (...args: any[]) => any; - /** - * Renders confirm/close buttons with callback function - */ - static createConfirmationContainer(container: HTMLElement, confirmText: string, cancelText: string, onConfirm: (Function: object) => void, onCancel: (Function: object) => void): void; - /** - * Renders a button with optional callback function - */ - static createButton(container: HTMLElement, text: string, className?: string[], visibility?: boolean, callback?: (Function: object) => void): void; - static _setAbsolutePosition(origin: HTMLElement, container: HTMLElement, position: string, margin: number, transitionMovement: number, align?: string): { - x: number; - y: number; - }; - static _repositionWithinScreen(x: number, y: number, width: number, height: number, margin: number, transitionMovement: number, align: string): { - x: number; - y: number; - }; -} - -interface ParallaxOptions extends BaseOptions$1 { - /** - * The minimum width of the screen, in pixels, where the parallax functionality starts working. - * @default 0 - */ - responsiveThreshold: number; -} -declare class Parallax extends Component { - private _enabled; - private _img; - static _parallaxes: Parallax[]; - static _handleScrollThrottled: () => Utils; - static _handleWindowResizeThrottled: () => Utils; - constructor(el: HTMLElement, options: Partial); - static get defaults(): ParallaxOptions; - /** - * Initializes instance of Parallax. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Parallax; - /** - * Initializes instances of Parallax. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Parallax[]; - static getInstance(el: HTMLElement): Parallax; - destroy(): void; - static _handleScroll(): void; - static _handleWindowResize(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _setupStyles(): void; - _handleImageLoad: () => void; - private _offset; - _updateParallax(): void; -} - -interface PushpinOptions extends BaseOptions$1 { - /** - * The distance in pixels from the top of the page where - * the element becomes fixed. - * @default 0 - */ - top: number; - /** - * The distance in pixels from the top of the page where - * the elements stops being fixed. - * @default Infinity - */ - bottom: number; - /** - * The offset from the top the element will be fixed at. - * @default 0 - */ - offset: number; - /** - * Callback function called when pushpin position changes. - * You are provided with a position string. - * @default null - */ - onPositionChange: (position: 'pinned' | 'pin-top' | 'pin-bottom') => void; -} -declare class Pushpin extends Component { - static _pushpins: Pushpin[]; - originalOffset: number; - constructor(el: HTMLElement, options: Partial); - static get defaults(): PushpinOptions; - /** - * Initializes instance of Pushpin. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Pushpin; - /** - * Initializes instances of Pushpin. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Pushpin[]; - static getInstance(el: HTMLElement): Pushpin; - destroy(): void; - static _updateElements(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _updatePosition(): void; - _removePinClasses(): void; -} - -interface ScrollSpyOptions extends BaseOptions$1 { - /** - * Throttle of scroll handler. - * @default 100 - */ - throttle: number; - /** - * Offset for centering element when scrolled to. - * @default 200 - */ - scrollOffset: number; - /** - * Class applied to active elements. - * @default 'active' - */ - activeClass: string; - /** - * Used to find active element. - * @default id => 'a[href="#' + id + '"]' - */ - getActiveElement: (id: string) => string; - /** - * Used to keep last top element active even if - * scrollbar goes outside of scrollspy elements. - * - * If there is no last top element, - * then the active one will be the first element. - * - * @default false - */ - keepTopElementActive: boolean; - /** - * Used to set scroll animation duration in milliseconds. - * @default null (browser's native animation implementation/duration) - */ - animationDuration: number | null; -} -declare class ScrollSpy extends Component { - static _elements: ScrollSpy[]; - static _count: number; - static _increment: number; - static _elementsInView: ScrollSpy[]; - static _visibleElements: HTMLElement[]; - static _ticks: number; - static _keptTopActiveElement: HTMLElement | null; - private tickId; - private id; - constructor(el: HTMLElement, options: Partial); - static get defaults(): ScrollSpyOptions; - /** - * Initializes instance of ScrollSpy. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): ScrollSpy; - /** - * Initializes instances of ScrollSpy. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): ScrollSpy[]; - static getInstance(el: HTMLElement): ScrollSpy; - destroy(): void; - _setupEventHandlers(): void; - _removeEventHandlers(): void; - _handleThrottledResize: () => void; - _handleTriggerClick: (e: MouseEvent) => void; - _handleWindowScroll: () => void; - static _offset(el: any): { - top: number; - left: number; - }; - static _findElements(top: number, right: number, bottom: number, left: number): ScrollSpy[]; - _enter(): void; - _exit(): void; - private _resetKeptTopActiveElementIfNeeded; - private static _getDistanceToViewport; - private static _smoothScrollIntoView; -} - -// type RGBColor = { -// r: number; -// g: number; -// b: number; -// }; - -// type Position = { -// x: number; -// y: number; -// }; - -class Waves { - /** - * - * @param {HTMLElement} el - * @returns - */ - static #offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - - // https://phoenix-dx.com/css-techniques-for-material-ripple-effect/ - - /** - * - * @param {HTMLElement} targetElement - * @param position - * @param color - */ - static renderWaveEffect(targetElement, position = null, color = null) { - const isCentered = position === null; - const duration = 500; - let animationFrame, animationStart; - - const animationStep = (timestamp) => { - if (!animationStart) animationStart = timestamp; - const frame = timestamp - animationStart; - if (frame < duration) { - const easing = (frame / duration) * (2 - frame / duration); - const circle = isCentered - ? 'circle at 50% 50%' - : `circle at ${position.x}px ${position.y}px`; - const waveColor = `rgba(${color?.r || 0}, ${color?.g || 0}, ${color?.b || 0}, ${0.3 * (1 - easing)})`; - const stop = 90 * easing + '%'; - targetElement.style.backgroundImage = - 'radial-gradient(' + - circle + - ', ' + - waveColor + - ' ' + - stop + - ', transparent ' + - stop + - ')'; - animationFrame = window.requestAnimationFrame(animationStep); - } else { - targetElement.style.backgroundImage = 'none'; - window.cancelAnimationFrame(animationFrame); - } - }; - - animationFrame = window.requestAnimationFrame(animationStep); - } - - static Init() { - if (typeof document !== 'undefined') - document?.addEventListener('DOMContentLoaded', () => { - document.body.addEventListener('click', (e) => { - const trigger = e.target; - const el = trigger.closest('.waves-effect'); - if (el && el.contains(trigger)) { - const isCircular = el.classList.contains('waves-circle'); - const x = e.pageX - this.#offset(el).left; - const y = e.pageY - this.#offset(el).top; - let color = null; - if (el.classList.contains('waves-light')) color = { r: 255, g: 255, b: 255 }; - this.renderWaveEffect(el, isCircular ? null : { x, y }, color); - } - }); - }); - } -} - -declare const version = "2.3.3"; -interface AutoInitOptions { - Autocomplete?: Partial; - Cards?: Partial; - Carousel?: Partial; - Chips?: Partial; - Collapsible?: Partial; - Datepicker?: Partial; - Dropdown?: Partial; - Materialbox?: Partial; - Modal?: Partial; - Parallax?: Partial; - Pushpin?: Partial; - ScrollSpy?: Partial; - FormSelect?: Partial; - Sidenav?: Partial; - Tabs?: Partial; - TapTarget?: Partial; - Timepicker?: Partial; - Tooltip?: Partial; - FloatingActionButton?: Partial; -} -/** - * Automatically initialize components. - * @param context Root element to initialize. Defaults to `document.body`. - * @param options Options for each component. - */ -declare function AutoInit(context?: HTMLElement, options?: Partial): void; - -export { AutoInit, Autocomplete, Cards, Carousel, CharacterCounter, Chips, Collapsible, Datepicker, Dropdown, FloatingActionButton, FormSelect, Forms, Materialbox, Modal, Parallax, Pushpin, Range, ScrollSpy, Sidenav, Slider, Tabs, TapTarget, Timepicker, Toast, Tooltip, Waves, version }; -export type { AutoInitOptions }; diff --git a/dist/js/materialize.js b/dist/js/materialize.js deleted file mode 100644 index 19d59fb6fd..0000000000 --- a/dist/js/materialize.js +++ /dev/null @@ -1,8409 +0,0 @@ -/*! -* Materialize v2.3.3 (https://materializeweb.com) -* Copyright 2014-2026 Materialize -* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE) -*/ -var M = (function (exports) { - 'use strict'; - - /** - * Class with utilitary functions for global usage. - */ - class Utils { - /** Specifies wether tab is pressed or not. */ - static tabPressed = false; - /** Specifies wether there is a key pressed. */ - static keyDown = false; - /** - * Key maps. - */ - static keys = { - TAB: ['Tab'], - ENTER: ['Enter'], - ESC: ['Escape', 'Esc'], - BACKSPACE: ['Backspace'], - ARROW_UP: ['ArrowUp', 'Up'], - ARROW_DOWN: ['ArrowDown', 'Down'], - ARROW_LEFT: ['ArrowLeft', 'Left'], - ARROW_RIGHT: ['ArrowRight', 'Right'], - DELETE: ['Delete', 'Del'] - }; - /** - * Detects when a key is pressed. - * @param e Event instance. - */ - static docHandleKeydown(e) { - Utils.keyDown = true; - if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) { - Utils.tabPressed = true; - } - } - /** - * Detects when a key is released. - * @param e Event instance. - */ - static docHandleKeyup(e) { - Utils.keyDown = false; - if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) { - Utils.tabPressed = false; - } - } - /** - * Detects when document is focused. - * @param e Event instance. - */ - /* eslint-disabled as of required event type condition check */ - /* eslint-disable-next-line */ - static docHandleFocus(e) { - if (Utils.keyDown) { - document.body.classList.add('keyboard-focused'); - } - } - /** - * Detects when document is not focused. - * @param e Event instance. - */ - /* eslint-disabled as of required event type condition check */ - /* eslint-disable-next-line */ - static docHandleBlur(e) { - document.body.classList.remove('keyboard-focused'); - } - /** - * Generates a unique string identifier. - */ - static guid() { - const s4 = () => { - return Math.floor((1 + Math.random()) * 0x10000) - .toString(16) - .substring(1); - }; - return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); - } - /** - * Checks for exceeded edges - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkWithinContainer(container, bounding, offset) { - const edges = { - top: false, - right: false, - bottom: false, - left: false - }; - const containerRect = container.getBoundingClientRect(); - // If body element is smaller than viewport, use viewport height instead. - const containerBottom = container === document.body - ? Math.max(containerRect.bottom, window.innerHeight) - : containerRect.bottom; - const scrollLeft = container.scrollLeft; - const scrollTop = container.scrollTop; - const scrolledX = bounding.left - scrollLeft; - const scrolledY = bounding.top - scrollTop; - // Check for container and viewport for each edge - if (scrolledX < containerRect.left + offset || scrolledX < offset) { - edges.left = true; - } - if (scrolledX + bounding.width > containerRect.right - offset || - scrolledX + bounding.width > window.innerWidth - offset) { - edges.right = true; - } - if (scrolledY < containerRect.top + offset || scrolledY < offset) { - edges.top = true; - } - if (scrolledY + bounding.height > containerBottom - offset || - scrolledY + bounding.height > window.innerHeight - offset) { - edges.bottom = true; - } - return edges; - } - /** - * Checks if element can be aligned in multiple directions. - * @param el Element to be inspected. - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkPossibleAlignments(el, container, bounding, offset) { - const canAlign = { - top: true, - right: true, - bottom: true, - left: true, - spaceOnTop: null, - spaceOnRight: null, - spaceOnBottom: null, - spaceOnLeft: null - }; - const containerAllowsOverflow = getComputedStyle(container).overflow === 'visible'; - const containerRect = container.getBoundingClientRect(); - const containerHeight = Math.min(containerRect.height, window.innerHeight); - const containerWidth = Math.min(containerRect.width, window.innerWidth); - const elOffsetRect = el.getBoundingClientRect(); - const scrollLeft = container.scrollLeft; - const scrollTop = container.scrollTop; - const scrolledX = bounding.left - scrollLeft; - const scrolledYTopEdge = bounding.top - scrollTop; - const scrolledYBottomEdge = bounding.top + elOffsetRect.height - scrollTop; - // Check for container and viewport for left - canAlign.spaceOnRight = !containerAllowsOverflow - ? containerWidth - (scrolledX + bounding.width) - : window.innerWidth - (elOffsetRect.left + bounding.width); - if (canAlign.spaceOnRight < 0) { - canAlign.left = false; - } - // Check for container and viewport for Right - canAlign.spaceOnLeft = !containerAllowsOverflow - ? scrolledX - bounding.width + elOffsetRect.width - : elOffsetRect.right - bounding.width; - if (canAlign.spaceOnLeft < 0) { - canAlign.right = false; - } - // Check for container and viewport for Top - canAlign.spaceOnBottom = !containerAllowsOverflow - ? containerHeight - (scrolledYTopEdge + bounding.height + offset) - : window.innerHeight - (elOffsetRect.top + bounding.height + offset); - if (canAlign.spaceOnBottom < 0) { - canAlign.top = false; - } - // Check for container and viewport for Bottom - canAlign.spaceOnTop = !containerAllowsOverflow - ? scrolledYBottomEdge - (bounding.height - offset) - : elOffsetRect.bottom - (bounding.height + offset); - if (canAlign.spaceOnTop < 0) { - canAlign.bottom = false; - } - return canAlign; - } - /** - * Retrieves target element id from trigger. - * @param trigger Trigger element. - */ - static getIdFromTrigger(trigger) { - let id = trigger.dataset.target; - if (!id) { - id = trigger.getAttribute('href'); - return id ? id.slice(1) : ''; - } - return id; - } - /** - * Retrieves document scroll postion from top. - */ - static getDocumentScrollTop() { - return window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0; - } - /** - * Retrieves document scroll postion from left. - */ - static getDocumentScrollLeft() { - return window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft || 0; - } - /** - * Fires the given function after a certain ammount of time. - * @param func Function to be fired. - * @param wait Wait time. - * @param options Additional options. - */ - static throttle(func, wait, options = {}) { - let context, args, result, timeout = null, previous = 0; - const later = () => { - previous = options.leading === false ? 0 : new Date().getTime(); - timeout = null; - result = func.apply(context, args); - context = args = null; - }; - return (...args) => { - const now = new Date().getTime(); - if (!previous && options.leading === false) - previous = now; - const remaining = wait - (now - previous); - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(this, args); - } - else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - } - /** - * Renders confirm/close buttons with callback function - */ - static createConfirmationContainer(container, confirmText, cancelText, onConfirm, onCancel) { - const confirmationButtonsContainer = document.createElement('div'); - confirmationButtonsContainer.classList.add('confirmation-btns'); - container.append(confirmationButtonsContainer); - this.createButton(confirmationButtonsContainer, cancelText, ['btn-cancel'], true, onCancel); - this.createButton(confirmationButtonsContainer, confirmText, ['btn-confirm'], true, onConfirm); - } - /** - * Renders a button with optional callback function - */ - static createButton(container, text, className = [], visibility = true, callback = null) { - className = className.concat(['btn', 'waves-effect', 'text']); - const button = document.createElement('button'); - button.className = className.join(' '); - button.style.visibility = visibility ? 'visible' : 'hidden'; - button.type = 'button'; - button.tabIndex = !!visibility ? 0 : -1; - button.innerText = text; - button.addEventListener('click', callback); - button.addEventListener('keypress', (e) => { - if (Utils.keys.ENTER.includes(e.key)) - callback(e); - }); - container.append(button); - } - static _setAbsolutePosition(origin, container, position, margin, transitionMovement, align = 'center') { - const originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, containerHeight = container.offsetHeight, containerWidth = container.offsetWidth; - let xMovement = 0, yMovement = 0, targetTop = origin.getBoundingClientRect().top + Utils.getDocumentScrollTop(), targetLeft = origin.getBoundingClientRect().left + Utils.getDocumentScrollLeft(); - if (position === 'top') { - targetTop += -containerHeight - margin; - if (align === 'center') { - targetLeft += originWidth / 2 - containerWidth / 2; // This is center align - } - yMovement = -transitionMovement; - } - else if (position === 'right') { - targetTop += originHeight / 2 - containerHeight / 2; - targetLeft = originWidth + margin; - xMovement = transitionMovement; - } - else if (position === 'left') { - targetTop += originHeight / 2 - containerHeight / 2; - targetLeft = -containerWidth - margin; - xMovement = -transitionMovement; - } - else { - targetTop += originHeight + margin; - if (align === 'center') { - targetLeft += originWidth / 2 - containerWidth / 2; // This is center align - } - yMovement = transitionMovement; - } - if (align === 'right') { - targetLeft += originWidth - containerWidth - margin; - } - const newCoordinates = Utils._repositionWithinScreen(targetLeft, targetTop, containerWidth, containerHeight, margin, transitionMovement, align); - container.style.top = newCoordinates.y + 'px'; - container.style.left = newCoordinates.x + 'px'; - return { x: xMovement, y: yMovement }; - } - static _repositionWithinScreen(x, y, width, height, margin, transitionMovement, align) { - const scrollLeft = Utils.getDocumentScrollLeft(); - const scrollTop = Utils.getDocumentScrollTop(); - let newX = x - scrollLeft; - let newY = y - scrollTop; - const bounding = { - left: newX, - top: newY, - width: width, - height: height - }; - let offset; - if (align === 'left' || align == 'center') { - offset = margin + transitionMovement; - } - else if (align === 'right') { - offset = margin - transitionMovement; - } - const edges = Utils.checkWithinContainer(document.body, bounding, offset); - if (edges.left) { - newX = offset; - } - else if (edges.right) { - newX -= newX + width - window.innerWidth; - } - if (edges.top) { - newY = offset; - } - else if (edges.bottom) { - newY -= newY + height - window.innerHeight; - } - return { - x: newX + scrollLeft, - y: newY + scrollTop - }; - } - } - - /** - * Base class implementation for Materialize components. - */ - class Component { - /** - * The DOM element the plugin was initialized with. - */ - el; - /** - * The options the instance was initialized with. - */ - options; - /** - * Constructs component instance and set everything up. - */ - constructor(el, options, classDef) { - // Display error if el is not a valid HTML Element - if (!(el instanceof HTMLElement)) { - console.error(Error(el + ' is not an HTML Element')); - } - // If exists, destroy and reinitialize in child - const ins = classDef.getInstance(el); - if (!!ins) { - ins.destroy(); - } - this.el = el; - } - /** - * Initializes component instances. - * @param els HTML elements. - * @param options Component options. - * @param classDef Class definition. - */ - static init(els, options, classDef) { - let instances = null; - if (els instanceof Element) { - instances = new classDef(els, options); - } - else if (!!els && els.length) { - instances = []; - for (let i = 0; i < els.length; i++) { - instances.push(new classDef(els[i], options)); - } - } - return instances; - } - /** - * @returns default options for component instance. - */ - static get defaults() { - return {}; - } - /** - * Retrieves component instance for the given element. - * @param el Associated HTML Element. - */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - static getInstance(el) { - throw new Error('This method must be implemented.'); - } - /** - * Destroy plugin instance and teardown. - */ - destroy() { - throw new Error('This method must be implemented.'); - } - } - - const _defaults$o = { - alignment: 'left', - autoFocus: true, - constrainWidth: true, - container: null, - coverTrigger: true, - closeOnClick: true, - hover: false, - inDuration: 150, - outDuration: 250, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - onItemClick: null - }; - class Dropdown extends Component { - static _dropdowns = []; - /** ID of the dropdown element. */ - id; - /** The DOM element of the dropdown. */ - dropdownEl; - /** If the dropdown is open. */ - isOpen; - /** If the dropdown content is scrollable. */ - isScrollable; - isTouchMoving; - /** The index of the item focused. */ - focusedIndex; - filterQuery; - filterTimeout; - constructor(el, options) { - super(el, options, Dropdown); - this.el['M_Dropdown'] = this; - Dropdown._dropdowns.push(this); - this.id = Utils.getIdFromTrigger(el); - this.dropdownEl = document.getElementById(this.id); - this.options = { - ...Dropdown.defaults, - ...options - }; - this.isOpen = false; - this.isScrollable = false; - this.isTouchMoving = false; - this.focusedIndex = -1; - this.filterQuery = []; - this.el.ariaExpanded = 'false'; - // Move dropdown-content after dropdown-trigger - this._moveDropdownToElement(); - this._makeDropdownFocusable(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$o; - } - /** - * Initializes instances of Dropdown. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Dropdown); - } - static getInstance(el) { - return el['M_Dropdown']; - } - destroy() { - this._resetDropdownStyles(); - this._removeEventHandlers(); - Dropdown._dropdowns.splice(Dropdown._dropdowns.indexOf(this), 1); - this.el['M_Dropdown'] = undefined; - } - _setupEventHandlers() { - // Trigger keydown handler - this.el.addEventListener('keydown', this._handleTriggerKeydown); - // Item click handler - this.dropdownEl?.addEventListener('click', this._handleDropdownClick); - // Hover event handlers - if (this.options.hover) { - this.el.addEventListener('mouseenter', this._handleMouseEnter); - this.el.addEventListener('mouseleave', this._handleMouseLeave); - this.dropdownEl.addEventListener('mouseleave', this._handleMouseLeave); - // Click event handlers - } - else { - this.el.addEventListener('click', this._handleClick); - } - } - _removeEventHandlers() { - this.el.removeEventListener('keydown', this._handleTriggerKeydown); - this.dropdownEl.removeEventListener('click', this._handleDropdownClick); - if (this.options.hover) { - this.el.removeEventListener('mouseenter', this._handleMouseEnter); - this.el.removeEventListener('mouseleave', this._handleMouseLeave); - this.dropdownEl.removeEventListener('mouseleave', this._handleMouseLeave); - } - else { - this.el.removeEventListener('click', this._handleClick); - } - } - _setupTemporaryEventHandlers() { - document.body.addEventListener('click', this._handleDocumentClick); - document.body.addEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.addEventListener('keydown', this._handleDropdownKeydown); - window.addEventListener('resize', this._handleWindowResize); - } - _removeTemporaryEventHandlers() { - document.body.removeEventListener('click', this._handleDocumentClick); - document.body.removeEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.removeEventListener('keydown', this._handleDropdownKeydown); - window.removeEventListener('resize', this._handleWindowResize); - } - _handleClick = (e) => { - e.preventDefault(); - //this._moveDropdown((e.target).closest('li')); - if (this.isOpen) { - this.close(); - } - else { - this.open(); - } - }; - _handleMouseEnter = () => { - //this._moveDropdown((e.target).closest('li')); - this.open(); - }; - _handleMouseLeave = (e) => { - const toEl = e.relatedTarget; - const leaveToDropdownContent = !!toEl.closest('.dropdown-content'); - let leaveToActiveDropdownTrigger = false; - const closestTrigger = toEl.closest('.dropdown-trigger'); - if (closestTrigger && !!closestTrigger['M_Dropdown'] && closestTrigger['M_Dropdown'].isOpen) { - leaveToActiveDropdownTrigger = true; - } - // Close hover dropdown if mouse did not leave to either active dropdown-trigger or dropdown-content - if (!leaveToActiveDropdownTrigger && !leaveToDropdownContent) { - this.close(); - } - }; - _handleDocumentClick = (e) => { - const target = e.target; - if (this.options.closeOnClick && target.closest('.dropdown-content') && !this.isTouchMoving) { - // isTouchMoving to check if scrolling on mobile. - this.close(); - } - else if (!target.closest('.dropdown-content')) { - // Do this one frame later so that if the element clicked also triggers _handleClick - // For example, if a label for a select was clicked, that we don't close/open the dropdown - setTimeout(() => { - if (this.isOpen) { - this.close(); - } - }, 0); - } - this.isTouchMoving = false; - }; - _handleTriggerKeydown = (e) => { - // ARROW DOWN OR ENTER WHEN SELECT IS CLOSED - open Dropdown - const arrowDownOrEnter = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ENTER.includes(e.key); - if (arrowDownOrEnter && !this.isOpen) { - e.preventDefault(); - this.open(); - } - }; - _handleDocumentTouchmove = (e) => { - const target = e.target; - if (target.closest('.dropdown-content')) { - this.isTouchMoving = true; - } - }; - _handleDropdownClick = (e) => { - // onItemClick callback - if (typeof this.options.onItemClick === 'function') { - const itemEl = e.target.closest('li'); - this.options.onItemClick.call(this, itemEl); - } - }; - _handleDropdownKeydown = (e) => { - const arrowUpOrDown = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ARROW_UP.includes(e.key); - if (Utils.keys.TAB.includes(e.key)) { - e.preventDefault(); - this.close(); - } - // Navigate down dropdown list - else if (arrowUpOrDown && this.isOpen) { - e.preventDefault(); - const direction = Utils.keys.ARROW_DOWN.includes(e.key) ? 1 : -1; - let newFocusedIndex = this.focusedIndex; - let hasFoundNewIndex = false; - do { - newFocusedIndex = newFocusedIndex + direction; - if (!!this.dropdownEl.children[newFocusedIndex] && - this.dropdownEl.children[newFocusedIndex].tabIndex !== -1) { - hasFoundNewIndex = true; - break; - } - } while (newFocusedIndex < this.dropdownEl.children.length && newFocusedIndex >= 0); - if (hasFoundNewIndex) { - // Remove active class from old element - if (this.focusedIndex >= 0) - this.dropdownEl.children[this.focusedIndex].classList.remove('active'); - this.focusedIndex = newFocusedIndex; - this._focusFocusedItem(); - } - } - // ENTER selects choice on focused item - else if (Utils.keys.ENTER.includes(e.key) && this.isOpen) { - // Search for and ` + - ''); - } - renderRow(days, isRTL, isRowSelected) { - return ('' + - (isRTL ? days.reverse() : days).join('') + - ''); - } - renderTable(opts, data, randId) { - return ('
' + - this.renderHead(opts) + - this.renderBody(data) + - '
'); - } - renderHead(opts) { - const arr = []; - let i; - for (i = 0; i < 7; i++) { - arr.push(`${this.renderDayName(opts, i, true)}`); - } - return '' + (opts.isRTL ? arr.reverse() : arr).join('') + ''; - } - renderBody(rows) { - return '' + rows.join('') + ''; - } - renderTitle(instance, c, year, month, refYear, randId) { - const opts = this.options, isMinYear = year === opts.minYear, isMaxYear = year === opts.maxYear; - let i, j, arr = [], html = '
', prev = true, next = true; - for (i = 0; i < 12; i++) { - arr.push(''); - } - const monthHtml = ''; - if (Array.isArray(opts.yearRange)) { - i = opts.yearRange[0]; - j = opts.yearRange[1] + 1; - } - else { - i = year - opts.yearRange; - j = 1 + year + opts.yearRange; - } - for (arr = []; i < j && i <= opts.maxYear; i++) { - if (i >= opts.minYear) { - arr.push(``); - } - } - if (opts.yearRangeReverse) - arr.reverse(); - const yearHtml = ``; - const leftArrow = ''; - html += ``; - html += '
'; - if (opts.showMonthAfterYear) { - html += yearHtml + monthHtml; - } - else { - html += monthHtml + yearHtml; - } - html += '
'; - if (isMinYear && (month === 0 || opts.minMonth >= month)) { - prev = false; - } - if (isMaxYear && (month === 11 || opts.maxMonth <= month)) { - next = false; - } - const rightArrow = ''; - html += ``; - return (html += '
'); - } - // refresh HTML - draw() { - const opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth; - let html = ''; - if (this._y <= minYear) { - this._y = minYear; - if (!isNaN(minMonth) && this._m < minMonth) { - this._m = minMonth; - } - } - if (this._y >= maxYear) { - this._y = maxYear; - if (!isNaN(maxMonth) && this._m > maxMonth) { - this._m = maxMonth; - } - } - const randId = 'datepicker-title-' + - Math.random() - .toString(36) - .replace(/[^a-z]+/g, '') - .substr(0, 2); - for (let c = 0; c < 1; c++) { - if (!this.options.isDateRange) { - this._renderDateDisplay(this.date); - } - else { - this._renderDateDisplay(this.date, this.endDate); - } - html += - this.renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId); - } - this.destroySelects(); - this.calendarEl.innerHTML = html; - // Init Materialize Select - const yearSelect = this.calendarEl.querySelector('.orig-select-year'); - const monthSelect = this.calendarEl.querySelector('.orig-select-month'); - // @todo fix accessibility @see https://github.com/materializecss/materialize/issues/522 - FormSelect.init(yearSelect, { - classes: 'select-year', - dropdownOptions: { container: document.body, constrainWidth: false } - }); - FormSelect.init(monthSelect, { - classes: 'select-month', - dropdownOptions: { container: document.body, constrainWidth: false } - }); - // Add change handlers for select - yearSelect.addEventListener('change', this._handleYearChange); - monthSelect.addEventListener('change', this._handleMonthChange); - if (typeof this.options.onDraw === 'function') { - this.options.onDraw.call(this); - } - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleInputClick); - this.el.addEventListener('keydown', this._handleInputKeydown); - this.el.addEventListener('change', this._handleInputChange); - this.calendarEl.addEventListener('click', this._handleCalendarClick); - } - _setupVariables() { - const template = document.createElement('template'); - template.innerHTML = Datepicker._template.trim(); - this.containerEl = template.content.firstChild; - this.calendarEl = this.containerEl.querySelector('.datepicker-calendar'); - this.yearTextEl = this.containerEl.querySelector('.year-text'); - this.dateTextEl = this.containerEl.querySelector('.date-text'); - this.footer = this.containerEl.querySelector('.datepicker-footer'); - this.formats = { - d: (date) => { - return date.getDate(); - }, - dd: (date) => { - const d = date.getDate(); - return (d < 10 ? '0' : '') + d; - }, - ddd: (date) => { - return this.options.i18n.weekdaysShort[date.getDay()]; - }, - dddd: (date) => { - return this.options.i18n.weekdays[date.getDay()]; - }, - m: (date) => { - return date.getMonth() + 1; - }, - mm: (date) => { - const m = date.getMonth() + 1; - return (m < 10 ? '0' : '') + m; - }, - mmm: (date) => { - return this.options.i18n.monthsShort[date.getMonth()]; - }, - mmmm: (date) => { - return this.options.i18n.months[date.getMonth()]; - }, - yy: (date) => { - return ('' + date.getFullYear()).slice(2); - }, - yyyy: (date) => { - return date.getFullYear(); - } - }; - } - _pickerSetup() { - if (!this.options.defaultDate) { - this.options.defaultDate = new Date(Date.parse(this.el.value)); - } - const defDate = this.options.defaultDate; - if (Datepicker._isDate(defDate)) { - if (this.options.setDefaultDate) { - this.setDate(defDate, true); - this.setInputValue(this.el, defDate); - } - else { - this.gotoDate(defDate); - } - } - else { - this.gotoDate(new Date()); - } - if (this.options.isDateRange) { - this.multiple = true; - const defEndDate = this.options.defaultEndDate; - if (Datepicker._isDate(defEndDate)) { - if (this.options.setDefaultEndDate) { - this.setDate(defEndDate, true, true); - this.setInputValue(this.endDateEl, defEndDate); - } - } - } - if (this.options.isMultipleSelection) { - this.multiple = true; - this.dates = []; - this.dateEls = []; - this.dateEls.push(this.el); - } - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleInputClick); - this.el.removeEventListener('keydown', this._handleInputKeydown); - this.el.removeEventListener('change', this._handleInputChange); - this.calendarEl.removeEventListener('click', this._handleCalendarClick); - if (this.options.isDateRange) { - this.endDateEl.removeEventListener('click', this._handleInputClick); - this.endDateEl.removeEventListener('keypress', this._handleInputKeydown); - this.endDateEl.removeEventListener('change', this._handleInputChange); - } - } - _handleInputClick = (e) => { - // Prevents default browser datepicker modal rendering - if (e.type == 'date') { - e.preventDefault(); - } - this.setDateFromInput(e.target); - this.draw(); - this.gotoDate(e.target === this.el ? this.date : this.endDate); - if (this.displayPlugin) - this.displayPlugin.show(); - if (this.options.onInputInteraction) - this.options.onInputInteraction.call(this); - }; - _handleInputKeydown = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this.setDateFromInput(e.target); - this.draw(); - if (this.displayPlugin) - this.displayPlugin.show(); - if (this.options.onInputInteraction) - this.options.onInputInteraction.call(this); - } - }; - _handleCalendarClick = (e) => { - const target = e.target; - if (!target.classList.contains('is-disabled')) { - if (target.classList.contains('datepicker-day-button') && - !target.classList.contains('is-empty') && - !target.parentElement.classList.contains('is-disabled')) { - const selectedDate = new Date(e.target.getAttribute('data-year'), e.target.getAttribute('data-month'), e.target.getAttribute('data-day')); - if (!this.multiple || (this.multiple && this.options.isMultipleSelection)) { - this.setDate(selectedDate); - } - if (this.options.isDateRange) { - const confirmAfterSelection = Datepicker._isDate(this.date) && this.options.autoSubmit; - this._handleDateRangeCalendarClick(selectedDate); - if (confirmAfterSelection) { - this._confirm(); - } - } - if (!this.options.isDateRange && this.options.autoSubmit) - this._confirm(); - } - else if (target.closest('.month-prev')) { - this.prevMonth(); - } - else if (target.closest('.month-next')) { - this.nextMonth(); - } - } - }; - _handleDateRangeCalendarClick = (date) => { - if (this.endDate == null || !Datepicker._compareDates(date, this.endDate)) { - if (Datepicker._isDate(this.date) && Datepicker._comparePastDate(date, this.date)) { - return; - } - this.setDate(date, true, Datepicker._isDate(this.date)); - return; - } - this._clearDates(); - this.draw(); - }; - _handleClearClick = () => { - this._clearDates(); - this.setInputValues(); - }; - _clearDates = () => { - this.date = null; - this.endDate = null; - this.draw(); - }; - _handleMonthChange = (e) => { - this.gotoMonth(e.target.value); - }; - _handleYearChange = (e) => { - this.gotoYear(e.target.value); - }; - // change view to a specific month (zero-index, e.g. 0: January) - gotoMonth(month) { - if (!isNaN(month)) { - this.calendars[0].month = parseInt(month, 10); - this.adjustCalendars(); - } - } - // change view to a specific full year (e.g. "2012") - gotoYear(year) { - if (!isNaN(year)) { - this.calendars[0].year = parseInt(year, 10); - this.adjustCalendars(); - } - } - _handleInputChange = (e) => { - let date; - const el = e.target; - // Prevent change event from being fired when triggered by the plugin - if (e['detail']?.firedBy === this) - return; - // Prevent change event from being fired if an end date is set without a start date - if (el == this.endDateEl && !this.date) - return; - if (this.options.parse) { - date = this.options.parse(e.target.value, typeof this.options.format === 'function' - ? this.options.format(new Date(this.el.value)) - : this.options.format); - } - else { - date = new Date(Date.parse(e.target.value)); - } - if (Datepicker._isDate(date)) { - this.setDate(date, false, el == this.endDateEl, true); - if (e.type == 'date') { - this.setDataDate(e, date); - this.setInputValues(); - } - } - }; - renderDayName(opts, day, abbr = false) { - day += opts.firstDay; - while (day >= 7) { - day -= 7; - } - return abbr ? opts.i18n.weekdaysAbbrev[day] : opts.i18n.weekdays[day]; - } - createDateInput() { - const dateInput = this.el.cloneNode(true); - dateInput.addEventListener('click', this._handleInputClick); - dateInput.addEventListener('keypress', this._handleInputKeydown); - dateInput.addEventListener('change', this._handleInputChange); - this.el.parentElement.appendChild(dateInput); - return dateInput; - } - // Set input value to the selected date and close Datepicker - _finishSelection = () => { - this.setInputValues(); - // Commented out because of function deprecations - // this.close(); - }; - _confirm = () => { - this._finishSelection(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onConfirm === 'function') - this.options.onConfirm.call(this); - }; - _cancel = () => { - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onCancel === 'function') - this.options.onCancel.call(this); - }; - // deprecated - open() { - console.warn('Datepicker.open() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - close() { - console.warn('Datepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - static { - Datepicker._template = ` -
-
- - -
-
-
- -
-
`; - } - } - - class Forms { - /** - * Checks if the label has validation and apply - * the correct class and styles - * @param textfield - */ - static validateField(textfield) { - if (!textfield) { - console.error('No text field element found'); - return; - } - const hasLength = textfield.getAttribute('data-length') !== null; - const lenAttr = parseInt(textfield.getAttribute('data-length')); - const len = textfield.value.length; - if (len === 0 && - textfield.validity.badInput === false && - !textfield.required && - textfield.classList.contains('validate')) { - textfield.classList.remove('invalid'); - } - else if (textfield.classList.contains('validate')) { - // Check for character counter attributes - if ((textfield.validity.valid && hasLength && len <= lenAttr) || - (textfield.validity.valid && !hasLength)) { - textfield.classList.remove('invalid'); - } - else { - textfield.classList.add('invalid'); - } - } - } - /** - * Resizes the given TextArea after updating the - * value content dynamically. - * @param e EventTarget - */ - static textareaAutoResize(e) { - const textarea = e; - // if (!textarea) { - // console.error('No textarea element found'); - // return; - // } - // Textarea Auto Resize - let hiddenDiv = document.querySelector('.hiddendiv'); - if (!hiddenDiv) { - hiddenDiv = document.createElement('div'); - hiddenDiv.classList.add('hiddendiv', 'common'); - document.body.append(hiddenDiv); - } - const style = getComputedStyle(textarea); - // Set font properties of hiddenDiv - const fontFamily = style.fontFamily; //textarea.css('font-family'); - const fontSize = style.fontSize; //textarea.css('font-size'); - const lineHeight = style.lineHeight; //textarea.css('line-height'); - // Firefox can't handle padding shorthand. - const paddingTop = style.paddingTop; //getComputedStyle(textarea).css('padding-top'); - const paddingRight = style.paddingRight; //textarea.css('padding-right'); - const paddingBottom = style.paddingBottom; //textarea.css('padding-bottom'); - const paddingLeft = style.paddingLeft; //textarea.css('padding-left'); - if (fontSize) - hiddenDiv.style.fontSize = fontSize; //('font-size', fontSize); - if (fontFamily) - hiddenDiv.style.fontFamily = fontFamily; //css('font-family', fontFamily); - if (lineHeight) - hiddenDiv.style.lineHeight = lineHeight; //css('line-height', lineHeight); - if (paddingTop) - hiddenDiv.style.paddingTop = paddingTop; //ss('padding-top', paddingTop); - if (paddingRight) - hiddenDiv.style.paddingRight = paddingRight; //css('padding-right', paddingRight); - if (paddingBottom) - hiddenDiv.style.paddingBottom = paddingBottom; //css('padding-bottom', paddingBottom); - if (paddingLeft) - hiddenDiv.style.paddingLeft = paddingLeft; //css('padding-left', paddingLeft); - // Set original-height, if none - if (!textarea.hasAttribute('original-height')) - textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString()); - if (textarea.getAttribute('wrap') === 'off') { - hiddenDiv.style.overflowWrap = 'normal'; // ('overflow-wrap', 'normal') - hiddenDiv.style.whiteSpace = 'pre'; //.css('white-space', 'pre'); - } - hiddenDiv.innerText = textarea.value + '\n'; - hiddenDiv.innerHTML = hiddenDiv.innerHTML.replace(/\n/g, '
'); - // When textarea is hidden, width goes crazy. - // Approximate with half of window size - if (textarea.offsetWidth > 0 && textarea.offsetHeight > 0) { - hiddenDiv.style.width = textarea.getBoundingClientRect().width + 'px'; // ('width', textarea.width() + 'px'); - } - else { - hiddenDiv.style.width = window.innerWidth / 2 + 'px'; //css('width', window.innerWidth / 2 + 'px'); - } - // Resize if the new height is greater than the - // original height of the textarea - const originalHeight = parseInt(textarea.getAttribute('original-height')); - const prevLength = parseInt(textarea.getAttribute('previous-length')); - if (isNaN(originalHeight)) - return; - if (originalHeight <= hiddenDiv.clientHeight) { - textarea.style.height = hiddenDiv.clientHeight + 'px'; //css('height', hiddenDiv.innerHeight() + 'px'); - } - else if (textarea.value.length < prevLength) { - // In case the new height is less than original height, it - // means the textarea has less text than before - // So we set the height to the original one - textarea.style.height = originalHeight + 'px'; - } - textarea.setAttribute('previous-length', (textarea.value || '').length.toString()); - } - static Init() { - if (typeof document !== 'undefined') - document?.addEventListener('DOMContentLoaded', () => { - document.addEventListener('change', (e) => { - const target = e.target; - if (target instanceof HTMLInputElement) { - if (target.value.length !== 0 || target.getAttribute('placeholder') !== null) { - for (const child of target.parentNode.children) { - if (child.tagName == 'label') { - child.classList.add('active'); - } - } - } - Forms.validateField(target); - } - }); - document.addEventListener('keyup', (e) => { - const target = e.target; - // Radio and Checkbox focus class - if (target instanceof HTMLInputElement && ['radio', 'checkbox'].includes(target.type)) { - // TAB, check if tabbing to radio or checkbox. - if (Utils.keys.TAB.includes(e.key)) { - target.classList.add('tabbed'); - target.addEventListener('blur', () => target.classList.remove('tabbed'), { - once: true - }); - } - } - }); - document - .querySelectorAll('.materialize-textarea') - .forEach((textArea) => { - Forms.InitTextarea(textArea); - }); - // File Input Path - document - .querySelectorAll('.file-field input[type="file"]') - .forEach((fileInput) => { - Forms.InitFileInputPath(fileInput); - }); - }); - } - static InitTextarea(textarea) { - // Save Data in Element - textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString()); - textarea.setAttribute('previous-length', (textarea.value || '').length.toString()); - Forms.textareaAutoResize(textarea); - textarea.addEventListener('keyup', (e) => Forms.textareaAutoResize(e.target)); - textarea.addEventListener('keydown', (e) => Forms.textareaAutoResize(e.target)); - } - static InitFileInputPath(fileInput) { - fileInput.addEventListener('change', () => { - const fileField = fileInput.closest('.file-field'); - const pathInput = fileField.querySelector('input.file-path'); - const files = fileInput.files; - const filenames = []; - for (let i = 0; i < files.length; i++) { - filenames.push(files[i].name); - } - pathInput.value = filenames.join(', '); - pathInput.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); - }); - } - } - - const _defaults$d = { - inDuration: 275, - outDuration: 200, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null - }; - class Materialbox extends Component { - /** If the materialbox overlay is showing. */ - overlayActive; - /** If the materialbox is no longer being animated. */ - doneAnimating; - /** Caption, if specified. */ - caption; - /** Original width of image. */ - originalWidth; - /** Original height of image. */ - originalHeight; - originInlineStyles; - placeholder; - _changedAncestorList; - newHeight; - newWidth; - windowWidth; - windowHeight; - attrWidth; - attrHeight; - _overlay; - _photoCaption; - constructor(el, options) { - super(el, options, Materialbox); - this.el['M_Materialbox'] = this; - this.options = { - ...Materialbox.defaults, - ...options - }; - this.overlayActive = false; - this.doneAnimating = true; - this.placeholder = document.createElement('div'); - this.placeholder.classList.add('material-placeholder'); - this.originalWidth = 0; - this.originalHeight = 0; - this.originInlineStyles = this.el.getAttribute('style'); - this.caption = this.el.getAttribute('data-caption') || ''; - this.el.tabIndex = 0; - // Wrap - this.el.before(this.placeholder); - this.placeholder.append(this.el); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$d; - } - /** - * Initializes instances of MaterialBox. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Materialbox); - } - static getInstance(el) { - return el['M_Materialbox']; - } - destroy() { - this._removeEventHandlers(); - this.el['M_Materialbox'] = undefined; - // Unwrap image - //this.placeholder.after(this.el).remove(); - this.placeholder.remove(); - this.el.removeAttribute('style'); - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleMaterialboxClick); - this.el.addEventListener('keypress', this._handleMaterialboxKeypress); - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleMaterialboxClick); - this.el.removeEventListener('keypress', this._handleMaterialboxKeypress); - } - _handleMaterialboxClick = () => { - this._handleMaterialboxToggle(); - }; - _handleMaterialboxKeypress = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleMaterialboxToggle(); - } - }; - _handleMaterialboxToggle = () => { - // If already modal, return to original - if (this.doneAnimating === false || (this.overlayActive && this.doneAnimating)) - this.close(); - else - this.open(); - }; - _handleWindowScroll = () => { - if (this.overlayActive) - this.close(); - }; - _handleWindowResize = () => { - if (this.overlayActive) - this.close(); - }; - _handleWindowEscape = (e) => { - if (Utils.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive) - this.close(); - }; - _makeAncestorsOverflowVisible() { - this._changedAncestorList = []; - let ancestor = this.placeholder.parentNode; - while (ancestor !== null && ancestor !== document) { - const curr = ancestor; - if (curr.style.overflow !== 'visible') { - curr.style.overflow = 'visible'; - this._changedAncestorList.push(curr); - } - ancestor = ancestor.parentNode; - } - } - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.scrollY - docElem.clientTop, - left: box.left + window.scrollX - docElem.clientLeft - }; - } - _updateVars() { - this.windowWidth = window.innerWidth; - this.windowHeight = window.innerHeight; - this.caption = this.el.getAttribute('data-caption') || ''; - } - // Image - _animateImageIn() { - this.el.style.maxHeight = this.newHeight.toString() + 'px'; - this.el.style.maxWidth = this.newWidth.toString() + 'px'; - const duration = this.options.inDuration; - // from - this.el.style.transition = 'none'; - this.el.style.height = this.originalHeight + 'px'; - this.el.style.width = this.originalWidth + 'px'; - setTimeout(() => { - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.newHeight + 'px'; - this.el.style.width = this.newWidth + 'px'; - this.el.style.left = - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2 + - 'px'; - this.el.style.top = - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2 + - 'px'; - }, 1); - setTimeout(() => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') - this.options.onOpenEnd.call(this, this.el); - }, duration); - /* - anim({ - targets: this.el, // image - height: [this.originalHeight, this.newHeight], - width: [this.originalWidth, this.newWidth], - left: - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2, - top: - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2, - - duration: this.options.inDuration, - easing: 'easeOutQuad', - complete: () => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el); - } - }); - */ - } - _animateImageOut() { - const duration = this.options.outDuration; - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.originalWidth + 'px'; - this.el.style.width = this.originalWidth + 'px'; - this.el.style.left = '0'; - this.el.style.top = '0'; - setTimeout(() => { - this.placeholder.style.height = ''; - this.placeholder.style.width = ''; - this.placeholder.style.position = ''; - this.placeholder.style.top = ''; - this.placeholder.style.left = ''; - // Revert to width or height attribute - if (this.attrWidth) - this.el.setAttribute('width', this.attrWidth.toString()); - if (this.attrHeight) - this.el.setAttribute('height', this.attrHeight.toString()); - this.el.removeAttribute('style'); - if (this.originInlineStyles) - this.el.setAttribute('style', this.originInlineStyles); - // Remove class - this.el.classList.remove('active'); - this.doneAnimating = true; - // Remove overflow overrides on ancestors - this._changedAncestorList.forEach((anchestor) => (anchestor.style.overflow = '')); - // onCloseEnd callback - if (typeof this.options.onCloseEnd === 'function') - this.options.onCloseEnd.call(this, this.el); - }, duration); - } - // Caption - _addCaption() { - this._photoCaption = document.createElement('div'); - this._photoCaption.classList.add('materialbox-caption'); - this._photoCaption.innerText = this.caption; - document.body.append(this._photoCaption); - this._photoCaption.style.display = 'inline'; - // Animate - this._photoCaption.style.transition = 'none'; - this._photoCaption.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '1'; - }, 1); - } - _removeCaption() { - const duration = this.options.outDuration; - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '0'; - setTimeout(() => { - this._photoCaption.remove(); - }, duration); - } - // Overlay - _addOverlay() { - this._overlay = document.createElement('div'); - this._overlay.id = 'materialbox-overlay'; - this._overlay.addEventListener('click', () => { - if (this.doneAnimating) - this.close(); - }, { once: true }); - // Put before in origin image to preserve z-index layering. - this.el.before(this._overlay); - // Set dimensions if needed - const overlayOffset = this._overlay.getBoundingClientRect(); - this._overlay.style.width = this.windowWidth + 'px'; - this._overlay.style.height = this.windowHeight + 'px'; - this._overlay.style.left = -1 * overlayOffset.left + 'px'; - this._overlay.style.top = -1 * overlayOffset.top + 'px'; - // Animate - this._overlay.style.transition = 'none'; - this._overlay.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '1'; - }, 1); - } - _removeOverlay() { - const duration = this.options.outDuration; - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '0'; - setTimeout(() => { - this.overlayActive = false; - this._overlay.remove(); - }, duration); - } - /** - * Open materialbox. - */ - open = () => { - this._updateVars(); - this.originalWidth = this.el.getBoundingClientRect().width; - this.originalHeight = this.el.getBoundingClientRect().height; - // Set states - this.doneAnimating = false; - this.el.classList.add('active'); - this.overlayActive = true; - // onOpenStart callback - if (typeof this.options.onOpenStart === 'function') - this.options.onOpenStart.call(this, this.el); - // Set positioning for placeholder - this.placeholder.style.width = this.placeholder.getBoundingClientRect().width + 'px'; - this.placeholder.style.height = this.placeholder.getBoundingClientRect().height + 'px'; - this.placeholder.style.position = 'relative'; - this.placeholder.style.top = '0'; - this.placeholder.style.left = '0'; - this._makeAncestorsOverflowVisible(); - // Set css on origin - this.el.style.position = 'absolute'; - this.el.style.zIndex = '1000'; - this.el.style.willChange = 'left, top, width, height'; - // Change from width or height attribute to css - this.attrWidth = this.el.getAttribute('width'); - this.attrHeight = this.el.getAttribute('height'); - if (this.attrWidth) { - this.el.style.width = this.attrWidth + 'px'; - this.el.removeAttribute('width'); - } - if (this.attrHeight) { - this.el.style.width = this.attrHeight + 'px'; - this.el.removeAttribute('height'); - } - this._addOverlay(); - // Add and animate caption if it exists - if (this.caption !== '') - this._addCaption(); - // Resize Image - const widthPercent = this.originalWidth / this.windowWidth; - const heightPercent = this.originalHeight / this.windowHeight; - this.newWidth = 0; - this.newHeight = 0; - if (widthPercent > heightPercent) { - // Width first - const ratio = this.originalHeight / this.originalWidth; - this.newWidth = this.windowWidth * 0.9; - this.newHeight = this.windowWidth * 0.9 * ratio; - } - else { - // Height first - const ratio = this.originalWidth / this.originalHeight; - this.newWidth = this.windowHeight * 0.9 * ratio; - this.newHeight = this.windowHeight * 0.9; - } - this._animateImageIn(); - // Handle Exit triggers - window.addEventListener('scroll', this._handleWindowScroll); - window.addEventListener('resize', this._handleWindowResize); - window.addEventListener('keyup', this._handleWindowEscape); - }; - /** - * Close materialbox. - */ - close = () => { - this._updateVars(); - this.doneAnimating = false; - // onCloseStart callback - if (typeof this.options.onCloseStart === 'function') - this.options.onCloseStart.call(this, this.el); - //anim.remove(this.el); - //anim.remove(this._overlay); - //if (this.caption !== '') anim.remove(this._photoCaption); - // disable exit handlers - window.removeEventListener('scroll', this._handleWindowScroll); - window.removeEventListener('resize', this._handleWindowResize); - window.removeEventListener('keyup', this._handleWindowEscape); - this._removeOverlay(); - this._animateImageOut(); - if (this.caption !== '') - this._removeCaption(); - }; - } - - const _defaults$c = { - opacity: 0.5, - inDuration: 250, - outDuration: 250, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - preventScrolling: true, - dismissible: true, - startingTop: '4%', - endingTop: '10%' - }; - class Modal extends Component { - constructor(el, options) { - super(el, options, Modal); - this.el['M_Modal'] = this; - this.options = { - ...Modal.defaults, - ...options - }; - this.el.tabIndex = 0; - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$c; - } - static init(els, options = {}) { - return super.init(els, options, Modal); - } - static getInstance(el) { - return el['M_Modal']; - } - destroy() { } - _setupEventHandlers() { } - _removeEventHandlers() { } - _handleTriggerClick() { } - _handleOverlayClick() { } - _handleModalCloseClick() { } - _handleKeydown() { } - _handleFocus() { } - open() { - return this; - } - close() { - return this; - } - // Experimental! - static #createHtml(config) { - return ` - ${config.header ? '' : ''} - - ${config.header ? '' : ''} - `; - } - static #createHtmlElement(config) { - const dialog = document.createElement('dialog'); - dialog.id = config.id; - return dialog; - } - static create(config) { - return this.#createHtmlElement(config); - } - static { } - } - - const _defaults$b = { - edge: 'left', - draggable: true, - dragTargetWidth: '10px', - inDuration: 250, - outDuration: 200, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - preventScrolling: true - }; - class Sidenav extends Component { - id; - /** Describes open/close state of Sidenav. */ - isOpen; - /** Describes if sidenav is fixed. */ - isFixed; - /** Describes if Sidenav is being dragged. */ - isDragged; - lastWindowWidth; - lastWindowHeight; - static _sidenavs; - _overlay; - dragTarget; - _startingXpos; - _xPos; - _time; - _width; - _initialScrollTop; - _verticallyScrolling; - deltaX; - velocityX; - percentOpen; - constructor(el, options) { - super(el, options, Sidenav); - this.el['M_Sidenav'] = this; - this.options = { - ...Sidenav.defaults, - ...options - }; - this.id = this.el.id; - this.isOpen = false; - this.isFixed = this.el.classList.contains('sidenav-fixed'); - this.isDragged = false; - // Window size variables for window resize checks - this.lastWindowWidth = window.innerWidth; - this.lastWindowHeight = window.innerHeight; - this._createOverlay(); - this._createDragTarget(); - this._setupEventHandlers(); - this._setupClasses(); - this._setupFixed(); - Sidenav._sidenavs.push(this); - } - static get defaults() { - return _defaults$b; - } - /** - * Initializes instances of Sidenav. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Sidenav); - } - static getInstance(el) { - return el['M_Sidenav']; - } - destroy() { - this._removeEventHandlers(); - this._enableBodyScrolling(); - this._overlay.parentNode.removeChild(this._overlay); - this.dragTarget.parentNode.removeChild(this.dragTarget); - this.el['M_Sidenav'] = undefined; - this.el.style.transform = ''; - const index = Sidenav._sidenavs.indexOf(this); - if (index >= 0) { - Sidenav._sidenavs.splice(index, 1); - } - } - _createOverlay() { - this._overlay = document.createElement('div'); - this._overlay.classList.add('sidenav-overlay'); - this._overlay.addEventListener('click', this.close); - document.body.appendChild(this._overlay); - } - _setupEventHandlers() { - if (Sidenav._sidenavs.length === 0) { - document.body.addEventListener('click', this._handleTriggerClick); - } - const passiveIfSupported = null; - this.dragTarget.addEventListener('touchmove', this._handleDragTargetDrag, passiveIfSupported); - this.dragTarget.addEventListener('touchend', this._handleDragTargetRelease); - this._overlay.addEventListener('touchmove', this._handleCloseDrag, passiveIfSupported); - this._overlay.addEventListener('touchend', this._handleCloseRelease); - this.el.addEventListener('touchmove', this._handleCloseDrag); // , passiveIfSupported); - this.el.addEventListener('touchend', this._handleCloseRelease); - this.el.addEventListener('click', this._handleCloseTriggerClick); - // Add resize for side nav fixed - if (this.isFixed) { - window.addEventListener('resize', this._handleWindowResize); - } - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - _removeEventHandlers() { - if (Sidenav._sidenavs.length === 1) { - document.body.removeEventListener('click', this._handleTriggerClick); - } - this.dragTarget.removeEventListener('touchmove', this._handleDragTargetDrag); - this.dragTarget.removeEventListener('touchend', this._handleDragTargetRelease); - this._overlay.removeEventListener('touchmove', this._handleCloseDrag); - this._overlay.removeEventListener('touchend', this._handleCloseRelease); - this.el.removeEventListener('touchmove', this._handleCloseDrag); - this.el.removeEventListener('touchend', this._handleCloseRelease); - this.el.removeEventListener('click', this._handleCloseTriggerClick); - // Remove resize for side nav fixed - if (this.isFixed) { - window.removeEventListener('resize', this._handleWindowResize); - } - } - _handleTriggerClick(e) { - const trigger = e.target.closest('.sidenav-trigger'); - if (e.target && trigger) { - const sidenavId = Utils.getIdFromTrigger(trigger); - const sidenavInstance = document.getElementById(sidenavId)['M_Sidenav']; - if (sidenavInstance) { - sidenavInstance.open(); - } - e.preventDefault(); - } - } - // Set variables needed at the beginning of drag and stop any current transition. - _startDrag(e) { - const clientX = e.targetTouches[0].clientX; - this.isDragged = true; - this._startingXpos = clientX; - this._xPos = this._startingXpos; - this._time = Date.now(); - this._width = this.el.getBoundingClientRect().width; - this._overlay.style.display = 'block'; - this._initialScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop(); - this._verticallyScrolling = false; - } - //Set variables needed at each drag move update tick - _dragMoveUpdate(e) { - const clientX = e.targetTouches[0].clientX; - const currentScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop(); - this.deltaX = Math.abs(this._xPos - clientX); - this._xPos = clientX; - this.velocityX = this.deltaX / (Date.now() - this._time); - this._time = Date.now(); - if (this._initialScrollTop !== currentScrollTop) { - this._verticallyScrolling = true; - } - } - _handleDragTargetDrag = (e) => { - // Check if draggable - if (!this._isDraggable()) - return; - let totalDeltaX = this._calculateDelta(e); - const dragDirection = totalDeltaX > 0 ? 'right' : 'left'; - // Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction - totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX)); - if (this.options.edge === dragDirection) { - totalDeltaX = 0; - } - /** - * transformX is the drag displacement - * transformPrefix is the initial transform placement - * Invert values if Sidenav is right edge - */ - let transformX = totalDeltaX; - let transformPrefix = 'translateX(-100%)'; - if (this.options.edge === 'right') { - transformPrefix = 'translateX(100%)'; - transformX = -transformX; - } - // Calculate open/close percentage of sidenav, with open = 1 and close = 0 - this.percentOpen = Math.min(1, totalDeltaX / this._width); - // Set transform and opacity styles - this.el.style.transform = `${transformPrefix} translateX(${transformX}px)`; - this._overlay.style.opacity = this.percentOpen.toString(); - }; - _handleDragTargetRelease = () => { - if (this.isDragged) { - if (this.percentOpen > 0.2) { - this.open(); - } - else { - this._animateOut(); - } - this.isDragged = false; - this._verticallyScrolling = false; - } - }; - _handleCloseDrag = (e) => { - // Check if open and draggable - if (!this.isOpen || !this._isDraggable()) - return; - let totalDeltaX = this._calculateDelta(e); - // dragDirection is the attempted user drag direction - const dragDirection = totalDeltaX > 0 ? 'right' : 'left'; - totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX)); - if (this.options.edge !== dragDirection) { - totalDeltaX = 0; - } - let transformX = -totalDeltaX; - if (this.options.edge === 'right') { - transformX = -transformX; - } - // Calculate open/close percentage of sidenav, with open = 1 and close = 0 - this.percentOpen = Math.min(1, 1 - totalDeltaX / this._width); - // Set transform and opacity styles - this.el.style.transform = `translateX(${transformX}px)`; - this._overlay.style.opacity = this.percentOpen.toString(); - }; - _calculateDelta = (e) => { - // If not being dragged, set initial drag start variables - if (!this.isDragged) { - this._startDrag(e); - } - // Run touchmove updates - this._dragMoveUpdate(e); - // Calculate raw deltaX - return this._xPos - this._startingXpos; - }; - _handleCloseRelease = () => { - if (this.isOpen && this.isDragged) { - if (this.percentOpen > 0.8) { - this._animateIn(); - } - else { - this.close(); - } - this.isDragged = false; - this._verticallyScrolling = false; - } - }; - // Handles closing of Sidenav when element with class .sidenav-close - _handleCloseTriggerClick = (e) => { - const closeTrigger = e.target.closest('.sidenav-close'); - if (closeTrigger && !this._isCurrentlyFixed()) { - this.close(); - } - }; - _handleWindowResize = () => { - // Only handle horizontal resizes - if (this.lastWindowWidth !== window.innerWidth) { - if (window.innerWidth > 992) { - this.open(); - } - else { - this.close(); - } - } - this.lastWindowWidth = window.innerWidth; - this.lastWindowHeight = window.innerHeight; - }; - _setupClasses() { - if (this.options.edge === 'right') { - this.el.classList.add('right-aligned'); - this.dragTarget.classList.add('right-aligned'); - } - } - _removeClasses() { - this.el.classList.remove('right-aligned'); - this.dragTarget.classList.remove('right-aligned'); - } - _setupFixed() { - if (this._isCurrentlyFixed()) - this.open(); - } - _isDraggable() { - return this.options.draggable && !this._isCurrentlyFixed() && !this._verticallyScrolling; - } - _isCurrentlyFixed() { - return this.isFixed && window.innerWidth > 992; - } - _createDragTarget() { - const dragTarget = document.createElement('div'); - dragTarget.classList.add('drag-target'); - dragTarget.style.width = this.options.dragTargetWidth; - document.body.appendChild(dragTarget); - this.dragTarget = dragTarget; - } - _preventBodyScrolling() { - document.body.style.overflow = 'hidden'; - } - _enableBodyScrolling() { - document.body.style.overflow = ''; - } - /** - * Opens Sidenav. - */ - open = () => { - if (this.isOpen === true) - return; - this.isOpen = true; - // Run onOpenStart callback - if (typeof this.options.onOpenStart === 'function') { - this.options.onOpenStart.call(this, this.el); - } - // Handle fixed Sidenav - if (this._isCurrentlyFixed()) { - // Show if fixed - this.el.style.transform = 'translateX(0)'; - this._enableBodyScrolling(); - this._overlay.style.display = 'none'; - } - // Handle non-fixed Sidenav - else { - if (this.options.preventScrolling) - this._preventBodyScrolling(); - if (!this.isDragged || this.percentOpen != 1) - this._animateIn(); - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - }; - /** - * Closes Sidenav. - */ - close = () => { - if (this.isOpen === false) - return; - this.isOpen = false; - // Run onCloseStart callback - if (typeof this.options.onCloseStart === 'function') { - this.options.onCloseStart.call(this, this.el); - } - // Handle fixed Sidenav - if (this._isCurrentlyFixed()) { - const transformX = this.options.edge === 'left' ? '-105%' : '105%'; - this.el.style.transform = `translateX(${transformX})`; - } - // Handle non-fixed Sidenav - else { - this._enableBodyScrolling(); - if (!this.isDragged || this.percentOpen != 0) { - this._animateOut(); - } - else { - this._overlay.style.display = 'none'; - } - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - }; - _animateIn() { - this._animateSidenavIn(); - this._animateOverlayIn(); - } - _animateOut() { - this._animateSidenavOut(); - this._animateOverlayOut(); - } - _animateSidenavIn() { - let slideOutPercent = this.options.edge === 'left' ? -1 : 1; - if (this.isDragged) { - slideOutPercent = - this.options.edge === 'left' - ? slideOutPercent + this.percentOpen - : slideOutPercent - this.percentOpen; - } - const duration = this.options.inDuration; - // from - this.el.style.transition = 'none'; - this.el.style.transform = 'translateX(' + slideOutPercent * 100 + '%)'; - setTimeout(() => { - this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad - // to - this.el.style.transform = 'translateX(0)'; - }, 1); - setTimeout(() => { - if (typeof this.options.onOpenEnd === 'function') - this.options.onOpenEnd.call(this, this.el); - }, duration); - } - _animateSidenavOut() { - const endPercent = this.options.edge === 'left' ? -1 : 1; - // let slideOutPercent = 0; - // if (this.isDragged) { - // // @todo unused variable - // slideOutPercent = - // this.options.edge === 'left' - // ? endPercent + this.percentOpen - // : endPercent - this.percentOpen; - // } - const duration = this.options.outDuration; - this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad - // to - this.el.style.transform = 'translateX(' + endPercent * 100 + '%)'; - setTimeout(() => { - if (typeof this.options.onCloseEnd === 'function') - this.options.onCloseEnd.call(this, this.el); - }, duration); - } - _animateOverlayIn() { - let start = 0; - if (this.isDragged) - start = this.percentOpen; - else - this._overlay.style.display = 'block'; - // Animation - const duration = this.options.inDuration; - // from - this._overlay.style.transition = 'none'; - this._overlay.style.opacity = start.toString(); - // easeOutQuad - setTimeout(() => { - this._overlay.style.transition = `opacity ${duration}ms ease`; - // to - this._overlay.style.opacity = '1'; - }, 1); - } - _animateOverlayOut() { - const duration = this.options.outDuration; - // easeOutQuad - this._overlay.style.transition = `opacity ${duration}ms ease`; - // to - this._overlay.style.opacity = '0'; - setTimeout(() => { - this._overlay.style.display = 'none'; - }, duration); - } - _setAriaHidden = () => { - this.el.ariaHidden = this.isOpen ? 'false' : 'true'; - const navWrapper = document.querySelector('.nav-wrapper ul'); - if (navWrapper) - navWrapper.ariaHidden = this.isOpen.toString(); - }; - _setTabIndex = () => { - const navLinks = document.querySelectorAll('.nav-wrapper ul li a'); - const sideNavLinks = document.querySelectorAll('.sidenav li a'); - if (navLinks) - navLinks.forEach((navLink) => { - navLink.tabIndex = this.isOpen ? -1 : 0; - }); - if (sideNavLinks) - sideNavLinks.forEach((sideNavLink) => { - sideNavLink.tabIndex = this.isOpen ? 0 : -1; - }); - }; - static { - Sidenav._sidenavs = []; - } - } - - const _defaults$a = { - indicators: true, - height: 400, - duration: 500, - interval: 6000, - pauseOnFocus: true, - pauseOnHover: true, - indicatorLabelFunc: null // Function which will generate a label for the indicators (ARIA) - }; - class Slider extends Component { - /** Index of current slide. */ - activeIndex; - interval; - eventPause; - _slider; - _slides; - _activeSlide; - _indicators; - _hovered; - _focused; - _focusCurrent; - _sliderId; - constructor(el, options) { - super(el, options, Slider); - this.el['M_Slider'] = this; - this.options = { - ...Slider.defaults, - ...options - }; - // init props - this.interval = null; - this.eventPause = false; - this._hovered = false; - this._focused = false; - this._focusCurrent = false; - // setup - this._slider = this.el.querySelector('.slides'); - this._slides = Array.from(this._slider.querySelectorAll('li')); - this.activeIndex = this._slides.findIndex((li) => li.classList.contains('active')); - if (this.activeIndex !== -1) { - this._activeSlide = this._slides[this.activeIndex]; - } - this._setSliderHeight(); - // Sets element id if it does not have one - if (this._slider.hasAttribute('id')) - this._sliderId = this._slider.getAttribute('id'); - else { - this._sliderId = 'slider-' + Utils.guid(); - this._slider.setAttribute('id', this._sliderId); - } - const placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; - // Set initial positions of captions - this._slides.forEach((slide) => { - // Caption - //const caption = slide.querySelector('.caption'); - //if (caption) this._animateCaptionIn(caption, 0); - // Set Images as Background Images - const img = slide.querySelector('img'); - if (img) { - if (img.src !== placeholderBase64) { - img.style.backgroundImage = 'url(' + img.src + ')'; - img.src = placeholderBase64; - } - } - // Sets slide as focusable by code - if (!slide.hasAttribute('tabindex')) - slide.setAttribute('tabindex', '-1'); - // Removes initial visibility from "inactive" slides - slide.style.visibility = 'hidden'; - }); - this._setupIndicators(); - // Show active slide - if (this._activeSlide) { - this._activeSlide.style.display = 'block'; - this._activeSlide.style.visibility = 'visible'; - } - else { - this.activeIndex = 0; - this._slides[0].classList.add('active'); - this._slides[0].style.visibility = 'visible'; - this._activeSlide = this._slides[0]; - this._animateSlide(this._slides[0], true); - // Update indicators - if (this.options.indicators) { - this._indicators[this.activeIndex].children[0].classList.add('active'); - } - } - this._setupEventHandlers(); - // auto scroll - this.start(); - } - static get defaults() { - return _defaults$a; - } - /** - * Initializes instances of Slider. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Slider); - } - static getInstance(el) { - return el['M_Slider']; - } - destroy() { - this.pause(); - this._removeIndicators(); - this._removeEventHandlers(); - this.el['M_Slider'] = undefined; - } - _setupEventHandlers() { - if (this.options.pauseOnFocus) { - this.el.addEventListener('focusin', this._handleAutoPauseFocus); - this.el.addEventListener('focusout', this._handleAutoStartFocus); - } - if (this.options.pauseOnHover) { - this.el.addEventListener('mouseenter', this._handleAutoPauseHover); - this.el.addEventListener('mouseleave', this._handleAutoStartHover); - } - if (this.options.indicators) { - this._indicators.forEach((el) => { - el.addEventListener('click', this._handleIndicatorClick); - }); - } - } - _removeEventHandlers() { - if (this.options.pauseOnFocus) { - this.el.removeEventListener('focusin', this._handleAutoPauseFocus); - this.el.removeEventListener('focusout', this._handleAutoStartFocus); - } - if (this.options.pauseOnHover) { - this.el.removeEventListener('mouseenter', this._handleAutoPauseHover); - this.el.removeEventListener('mouseleave', this._handleAutoStartHover); - } - if (this.options.indicators) { - this._indicators.forEach((el) => { - el.removeEventListener('click', this._handleIndicatorClick); - }); - } - } - _handleIndicatorClick = (e) => { - const el = e.target.parentElement; - const currIndex = [...el.parentNode.children].indexOf(el); - this._focusCurrent = true; - this.set(currIndex); - }; - _handleAutoPauseHover = () => { - this._hovered = true; - if (this.interval != null) { - this._pause(true); - } - }; - _handleAutoPauseFocus = () => { - this._focused = true; - if (this.interval != null) { - this._pause(true); - } - }; - _handleAutoStartHover = () => { - this._hovered = false; - if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) { - this.start(); - } - }; - _handleAutoStartFocus = () => { - this._focused = false; - if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) { - this.start(); - } - }; - _handleInterval = () => { - const activeElem = this._slider.querySelector('.active'); - let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem); - if (this._slides.length === newActiveIndex + 1) - newActiveIndex = 0; // loop to start - else - newActiveIndex += 1; - this.set(newActiveIndex); - }; - _animateSlide(slide, isDirectionIn) { - let dx = 0, dy = 0; - // from - slide.style.opacity = isDirectionIn ? '0' : '1'; - setTimeout(() => { - slide.style.transition = `opacity ${this.options.duration}ms ease`; - // to - slide.style.opacity = isDirectionIn ? '1' : '0'; - }, 1); - // Caption - const caption = slide.querySelector('.caption'); - if (!caption) - return; - if (caption.classList.contains('center-align')) - dy = -100; - else if (caption.classList.contains('right-align')) - dx = 100; - else if (caption.classList.contains('left-align')) - dx = -100; - // from - caption.style.opacity = isDirectionIn ? '0' : '1'; - caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`; - setTimeout(() => { - caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`; - // to - caption.style.opacity = isDirectionIn ? '1' : '0'; - caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`; - }, this.options.duration); // delay - } - _setSliderHeight() { - // If fullscreen, do nothing - if (!this.el.classList.contains('fullscreen')) { - if (this.options.indicators) { - // Add height if indicators are present - this.el.style.height = this.options.height + 40 + 'px'; //.css('height', this.options.height + 40 + 'px'); - } - else { - this.el.style.height = this.options.height + 'px'; - } - this._slider.style.height = this.options.height + 'px'; - } - } - _setupIndicators() { - if (this.options.indicators) { - const ul = document.createElement('ul'); - ul.classList.add('indicators'); - const arrLi = []; - this._slides.forEach((el, i) => { - const label = this.options.indicatorLabelFunc - ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0) - : `${i + 1}`; - const li = document.createElement('li'); - li.classList.add('indicator-item'); - li.innerHTML = ``; - arrLi.push(li); - ul.append(li); - }); - this.el.append(ul); - this._indicators = arrLi; - } - } - _removeIndicators() { - this.el.querySelector('ul.indicators').remove(); //find('ul.indicators').remove(); - } - set(index) { - // Wrap around indices. - if (index >= this._slides.length) - index = 0; - else if (index < 0) - index = this._slides.length - 1; - // Only do if index changes - if (this.activeIndex === index) - return; - this._activeSlide = this._slides[this.activeIndex]; - const _caption = this._activeSlide.querySelector('.caption'); - this._activeSlide.classList.remove('active'); - // Enables every slide - this._slides.forEach((slide) => (slide.style.visibility = 'visible')); - //--- Hide active Slide + Caption - this._activeSlide.style.opacity = '0'; - setTimeout(() => { - this._slides.forEach((slide) => { - if (slide.classList.contains('active')) - return; - slide.style.opacity = '0'; - slide.style.transform = 'translate(0, 0)'; - // Disables invisible slides (for assistive technologies) - slide.style.visibility = 'hidden'; - }); - }, this.options.duration); - // Hide active Caption - //this._animateCaptionIn(_caption, this.options.duration); - _caption.style.opacity = '0'; - // Update indicators - if (this.options.indicators) { - const activeIndicator = this._indicators[this.activeIndex].children[0]; - const nextIndicator = this._indicators[index].children[0]; - activeIndicator.classList.remove('active'); - nextIndicator.classList.add('active'); - if (typeof this.options.indicatorLabelFunc === 'function') { - activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, this.activeIndex, false); - nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true); - } - } - //--- Show new Slide + Caption - this._animateSlide(this._slides[index], true); - this._slides[index].classList.add('active'); - this.activeIndex = index; - // Reset interval, if allowed. This check prevents autostart - // when slider is paused, since it can be changed though indicators. - if (this.interval != null) { - this.start(); - } - } - _pause(fromEvent) { - clearInterval(this.interval); - this.eventPause = fromEvent; - this.interval = null; - } - /** - * Pause slider autoslide. - */ - pause = () => { - this._pause(false); - }; - /** - * Start slider autoslide. - */ - start = () => { - clearInterval(this.interval); - this.interval = setInterval(this._handleInterval, this.options.duration + this.options.interval); - this.eventPause = false; - }; - /** - * Move to next slider. - */ - next = () => { - let newIndex = this.activeIndex + 1; - // Wrap around indices. - if (newIndex >= this._slides.length) - newIndex = 0; - else if (newIndex < 0) - newIndex = this._slides.length - 1; - this.set(newIndex); - }; - /** - * Move to prev slider. - */ - prev = () => { - let newIndex = this.activeIndex - 1; - // Wrap around indices. - if (newIndex >= this._slides.length) - newIndex = 0; - else if (newIndex < 0) - newIndex = this._slides.length - 1; - this.set(newIndex); - }; - } - - const _defaults$9 = { - duration: 300, - onShow: null, - swipeable: false, - responsiveThreshold: Infinity // breakpoint for swipeable - }; - class Tabs extends Component { - _tabLinks; - _index; - _indicator; - _tabWidth; - _tabsWidth; - _tabsCarousel; - _activeTabLink; - _content; - constructor(el, options) { - super(el, options, Tabs); - this.el['M_Tabs'] = this; - this.options = { - ...Tabs.defaults, - ...options - }; - this._tabLinks = this.el.querySelectorAll('li.tab > a'); - this._index = 0; - this._setupActiveTabLink(); - if (this.options.swipeable) { - this._setupSwipeableTabs(); - } - else { - this._setupNormalTabs(); - } - // Setup tabs indicator after content to ensure accurate widths - this._setTabsAndTabWidth(); - this._createIndicator(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$9; - } - /** - * Initializes instances of Tabs. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Tabs); - } - static getInstance(el) { - return el['M_Tabs']; - } - destroy() { - this._removeEventHandlers(); - this._indicator.parentNode.removeChild(this._indicator); - if (this.options.swipeable) { - this._teardownSwipeableTabs(); - } - else { - this._teardownNormalTabs(); - } - this.el['M_Tabs'] = undefined; - } - /** - * The index of tab that is currently shown. - */ - get index() { - return this._index; - } - _setupEventHandlers() { - window.addEventListener('resize', this._handleWindowResize); - this.el.addEventListener('click', this._handleTabClick); - // map vertical scrolling to horizontal scrolling because no scrollbar is shown on desktop - this.el.addEventListener('wheel', (event) => { - if (event.deltaY !== 0) { - event.preventDefault(); - this.el.scrollLeft += event.deltaY * 1; - } - }); - } - _removeEventHandlers() { - window.removeEventListener('resize', this._handleWindowResize); - this.el.removeEventListener('click', this._handleTabClick); - } - _handleWindowResize = () => { - this._setTabsAndTabWidth(); - if (this._tabWidth !== 0 && this._tabsWidth !== 0) { - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - }; - _handleTabClick = (e) => { - let tabLink = e.target; - if (!tabLink) - return; - let tab = tabLink.parentElement; - while (tab && !tab.classList.contains('tab')) { - tabLink = tabLink.parentElement; - tab = tab.parentElement; - } - // Handle click on tab link only - if (!tabLink || !tab.classList.contains('tab')) - return; - // is disabled? - if (tab.classList.contains('disabled')) { - e.preventDefault(); - return; - } - // Act as regular link if target attribute is specified. - if (tabLink.hasAttribute('target')) - return; - // Make the old tab inactive. - this._activeTabLink.classList.remove('active'); - const _oldContent = this._content; - // Update the variables with the new link and content - this._activeTabLink = tabLink; - if (tabLink.hash) - this._content = document.querySelector(tabLink.hash); - this._tabLinks = this.el.querySelectorAll('li.tab > a'); - // Make the tab active - this._activeTabLink.classList.add('active'); - const prevIndex = this._index; - this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0); - // Swap content - if (this.options.swipeable) { - if (this._tabsCarousel) { - this._tabsCarousel.set(this._index, () => { - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - }); - } - } - else { - if (this._content) { - this._content.style.display = 'block'; - this._content.classList.add('active'); - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - if (_oldContent && _oldContent !== this._content) { - _oldContent.style.display = 'none'; - _oldContent.classList.remove('active'); - } - } - } - // Update widths after content is swapped (scrollbar bugfix) - this._setTabsAndTabWidth(); - this._animateIndicator(prevIndex); - e.preventDefault(); - }; - _createIndicator() { - const indicator = document.createElement('li'); - indicator.classList.add('indicator'); - this.el.appendChild(indicator); - this._indicator = indicator; - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - _setupActiveTabLink() { - // If the location.hash matches one of the links, use that as the active tab. - this._activeTabLink = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === location.hash); - // If no match is found, use the first link or any with class 'active' as the initial active tab. - if (!this._activeTabLink) { - let activeTabLink = this.el.querySelector('li.tab a.active'); - if (!activeTabLink) { - activeTabLink = this.el.querySelector('li.tab a'); - } - this._activeTabLink = activeTabLink; - } - Array.from(this._tabLinks).forEach((a) => a.classList.remove('active')); - this._activeTabLink.classList.add('active'); - this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0); - if (this._activeTabLink && this._activeTabLink.hash) { - this._content = document.querySelector(this._activeTabLink.hash); - if (this._content) - this._content.classList.add('active'); - } - } - _setupSwipeableTabs() { - // Change swipeable according to responsive threshold - if (window.innerWidth > this.options.responsiveThreshold) - this.options.swipeable = false; - const tabsContent = []; - this._tabLinks.forEach((a) => { - if (a.hash) { - const currContent = document.querySelector(a.hash); - currContent.classList.add('carousel-item'); - tabsContent.push(currContent); - } - }); - // Create Carousel-Wrapper around Tab-Contents - const tabsWrapper = document.createElement('div'); - tabsWrapper.classList.add('tabs-content', 'carousel', 'carousel-slider'); - // Wrap around - tabsContent[0].parentElement.insertBefore(tabsWrapper, tabsContent[0]); - tabsContent.forEach((tabContent) => { - tabsWrapper.appendChild(tabContent); - tabContent.style.display = ''; - }); - // Keep active tab index to set initial carousel slide - const tab = this._activeTabLink.parentElement; - const activeTabIndex = Array.from(tab.parentNode.children).indexOf(tab); - this._tabsCarousel = Carousel.init(tabsWrapper, { - fullWidth: true, - noWrap: true, - onCycleTo: (item) => { - const prevIndex = this._index; - this._index = Array.from(item.parentNode.children).indexOf(item); - this._activeTabLink.classList.remove('active'); - this._activeTabLink = Array.from(this._tabLinks)[this._index]; - this._activeTabLink.classList.add('active'); - this._animateIndicator(prevIndex); - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - } - }); - // Set initial carousel slide to active tab - this._tabsCarousel.set(activeTabIndex); - } - _teardownSwipeableTabs() { - const tabsWrapper = this._tabsCarousel.el; - this._tabsCarousel.destroy(); - // Unwrap - tabsWrapper.append(tabsWrapper.parentElement); - tabsWrapper.remove(); - } - _setupNormalTabs() { - // Hide Tabs Content - Array.from(this._tabLinks).forEach((a) => { - if (a === this._activeTabLink) - return; - if (a.hash) { - const currContent = document.querySelector(a.hash); - if (currContent) - currContent.style.display = 'none'; - } - }); - } - _teardownNormalTabs() { - // show Tabs Content - this._tabLinks.forEach((a) => { - if (a.hash) { - const currContent = document.querySelector(a.hash); - if (currContent) - currContent.style.display = ''; - } - }); - } - _setTabsAndTabWidth() { - this._tabsWidth = this.el.getBoundingClientRect().width; - this._tabWidth = Math.max(this._tabsWidth, this.el.scrollWidth) / this._tabLinks.length; - } - _calcRightPos(el) { - return Math.ceil(this._tabsWidth - el.offsetLeft - el.getBoundingClientRect().width); - } - _calcLeftPos(el) { - return Math.floor(el.offsetLeft); - } - /** - * Recalculate tab indicator position. This is useful when - * the indicator position is not correct. - */ - updateTabIndicator() { - this._setTabsAndTabWidth(); - this._animateIndicator(this._index); - } - _animateIndicator(prevIndex) { - let leftDelay = 0, rightDelay = 0; - const isMovingLeftOrStaying = this._index - prevIndex >= 0; - if (isMovingLeftOrStaying) - leftDelay = 90; - else - rightDelay = 90; - // in v1: easeOutQuad - this._indicator.style.transition = ` - left ${this.options.duration}ms ease-out ${leftDelay}ms, - right ${this.options.duration}ms ease-out ${rightDelay}ms`; - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - /** - * Show tab content that corresponds to the tab with the id. - * @param tabId The id of the tab that you want to switch to. - */ - select(tabId) { - const tab = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === '#' + tabId); - if (tab) - tab.click(); - } - } - - const _defaults$8 = { - dialRadius: 135, - outerRadius: 105, - innerRadius: 70, - tickRadius: 20, - duration: 350, - container: null, - defaultTime: 'now', // default time, 'now' or '13:14' e.g. - fromNow: 0, // Millisecond offset from the defaultTime - showClearBtn: false, - autoSubmit: true, - // internationalization - i18n: { - cancel: 'Cancel', - clear: 'Clear', - done: 'Ok' - }, - twelveHour: true, // change to 12 hour AM/PM clock from 24 hour - vibrate: true, // vibrate the device when dragging clock hand - // Callbacks - onSelect: null, - onInputInteraction: null, - onDone: null, - onCancel: null, - displayPlugin: null, - displayPluginOptions: null - }; - class Timepicker extends Component { - id; - containerEl; - plate; - digitalClock; - inputHours; - inputMinutes; - x0; - y0; - moved; - dx; - dy; - /** - * Current view on the timepicker. - * @default 'hours' - */ - currentView; - hand; - minutesView; - hours; - minutes; - /** The selected time. */ - time; - /** - * If the time is AM or PM on twelve-hour clock. - * @default 'PM' - */ - amOrPm; - static _template; - /** Vibrate device when dragging clock hand. */ - vibrate; - _canvas; - hoursView; - spanAmPm; - footer; - _amBtn; - _pmBtn; - bg; - bearing; - g; - toggleViewTimer; - vibrateTimer; - displayPlugin; - constructor(el, options) { - super(el, options, Timepicker); - this.el['M_Timepicker'] = this; - this.options = { - ...Timepicker.defaults, - ...options - }; - this.id = Utils.guid(); - this._insertHTMLIntoDOM(); - this._setupVariables(); - this._setupEventHandlers(); - this._clockSetup(); - if (this.options.displayPlugin) - this._setupDisplayPlugin(); - this._pickerSetup(); - } - static get defaults() { - return _defaults$8; - } - /** - * Initializes instances of Timepicker. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Timepicker); - } - static _addLeadingZero(num) { - return (num < 10 ? '0' : '') + num; - } - static _createSVGEl(name) { - const svgNS = 'http://www.w3.org/2000/svg'; - return document.createElementNS(svgNS, name); - } - static _Pos(e) { - if (e.type.startsWith('touch') && e.targetTouches.length >= 1) { - return { - x: e.targetTouches[0].clientX, - y: e.targetTouches[0].clientY - }; - } - // mouse event - return { x: e.clientX, y: e.clientY }; - } - static getInstance(el) { - return el['M_Timepicker']; - } - destroy() { - this._removeEventHandlers(); - this.containerEl.remove(); - this.el['M_Timepicker'] = undefined; - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleInputClick); - // @todo allow input field to fill values from input field when container/modal opens - this.el.addEventListener('keydown', this._handleInputKeydown); - this.plate.addEventListener('mousedown', this._handleClockClickStart); - this.plate.addEventListener('touchstart', this._handleClockClickStart); - this.digitalClock.addEventListener('keyup', this._inputFromTextField); - this.inputHours.addEventListener('focus', () => this.showView('hours')); - this.inputHours.addEventListener('focusout', () => this.formatHours()); - this.inputMinutes.addEventListener('focus', () => this.showView('minutes')); - this.inputMinutes.addEventListener('focusout', () => this.formatMinutes()); - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleInputClick); - this.el.removeEventListener('keydown', this._handleInputKeydown); - } - _handleInputClick = () => { - this.inputHours.focus(); - if (typeof this.options.onInputInteraction === 'function') - this.options.onInputInteraction.call(this); - if (this.displayPlugin) - this.displayPlugin.show(); - }; - _handleInputKeydown = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this.inputHours.focus(); - if (typeof this.options.onInputInteraction === 'function') - this.options.onInputInteraction.call(this); - if (this.displayPlugin) - this.displayPlugin.show(); - } - }; - _handleTimeInputEnterKey = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this._inputFromTextField(); - } - }; - _handleClockClickStart = (e) => { - e.preventDefault(); - const clockPlateBR = this.plate.getBoundingClientRect(); - const offset = { x: clockPlateBR.left, y: clockPlateBR.top }; - this.x0 = offset.x + this.options.dialRadius; - this.y0 = offset.y + this.options.dialRadius; - this.moved = false; - const clickPos = Timepicker._Pos(e); - this.dx = clickPos.x - this.x0; - this.dy = clickPos.y - this.y0; - // Set clock hands - this.setHand(this.dx, this.dy, false); - // Mousemove on document - document.addEventListener('mousemove', this._handleDocumentClickMove); - document.addEventListener('touchmove', this._handleDocumentClickMove); - // Mouseup on document - document.addEventListener('mouseup', this._handleDocumentClickEnd); - document.addEventListener('touchend', this._handleDocumentClickEnd); - }; - _handleDocumentClickMove = (e) => { - e.preventDefault(); - const clickPos = Timepicker._Pos(e); - const x = clickPos.x - this.x0; - const y = clickPos.y - this.y0; - this.moved = true; - this.setHand(x, y, false); - }; - _handleDocumentClickEnd = (e) => { - e.preventDefault(); - document.removeEventListener('mouseup', this._handleDocumentClickEnd); - document.removeEventListener('touchend', this._handleDocumentClickEnd); - const clickPos = Timepicker._Pos(e); - const x = clickPos.x - this.x0; - const y = clickPos.y - this.y0; - if (this.moved && x === this.dx && y === this.dy) { - this.setHand(x, y); - } - if (this.currentView === 'hours') { - this.inputMinutes.focus(); - this.showView('minutes', this.options.duration / 2); - } - else { - // this.minutesView.classList.add('timepicker-dial-out'); - setTimeout(() => { - if (this.options.autoSubmit) - this.done(); - }, this.options.duration / 2); - } - if (typeof this.options.onSelect === 'function') { - this.options.onSelect.call(this, this.hours, this.minutes); - } - // Unbind mousemove event - document.removeEventListener('mousemove', this._handleDocumentClickMove); - document.removeEventListener('touchmove', this._handleDocumentClickMove); - }; - _insertHTMLIntoDOM() { - const template = document.createElement('template'); - template.innerHTML = Timepicker._template.trim(); - this.containerEl = template.content.firstChild; - this.containerEl.id = 'container-' + this.id; - // Append popover to input by default - const optEl = this.options.container; - const containerEl = optEl instanceof HTMLElement ? optEl : document.querySelector(optEl); - if (this.options.container && !!containerEl) { - containerEl.append(this.containerEl); - } - else { - this.el.parentElement.appendChild(this.containerEl); - } - } - _setupVariables() { - this.currentView = 'hours'; - this.vibrate = navigator.vibrate - ? 'vibrate' - : navigator['webkitVibrate'] - ? 'webkitVibrate' - : null; - this._canvas = this.containerEl.querySelector('.timepicker-canvas'); - this.plate = this.containerEl.querySelector('.timepicker-plate'); - this.digitalClock = this.containerEl.querySelector('.timepicker-display-column'); - this.hoursView = this.containerEl.querySelector('.timepicker-hours'); - this.minutesView = this.containerEl.querySelector('.timepicker-minutes'); - this.inputHours = this.containerEl.querySelector('.timepicker-input-hours'); - this.inputMinutes = this.containerEl.querySelector('.timepicker-input-minutes'); - this.spanAmPm = this.containerEl.querySelector('.timepicker-span-am-pm'); - this.footer = this.containerEl.querySelector('.timepicker-footer'); - this.amOrPm = 'PM'; - } - /*private _createButton(text: string, visibility: string): HTMLButtonElement { - const button = document.createElement('button'); - button.classList.add('btn', 'waves-effect', 'text'); - button.style.visibility = visibility; - button.type = 'button'; - button.tabIndex = -1; - button.innerText = text; - return button; - }*/ - _pickerSetup() { - // clearButton.classList.add('timepicker-clear'); - // clearButton.addEventListener('click', this.clear); - // this.footer.appendChild(clearButton); - if (this.options.showClearBtn) { - Utils.createButton(this.footer, this.options.i18n.clear, ['timepicker-clear'], true, this.clear); - } - if (!this.options.autoSubmit) { - /*const confirmationBtnsContainer = document.createElement('div'); - confirmationBtnsContainer.classList.add('confirmation-btns'); - this.footer.append(confirmationBtnsContainer); - - const cancelButton = this._createButton(this.options.i18n.cancel, ''); - cancelButton.classList.add('timepicker-close'); - cancelButton.addEventListener('click', this.close); - confirmationBtnsContainer.appendChild(cancelButton); - - const doneButton = this._createButton(this.options.i18n.done, ''); - doneButton.classList.add('timepicker-close'); - //doneButton.addEventListener('click', this._finishSelection); - confirmationBtnsContainer.appendChild(doneButton);*/ - Utils.createConfirmationContainer(this.footer, this.options.i18n.done, this.options.i18n.cancel, this.confirm, this.cancel); - } - this._updateTimeFromInput(); - this.showView('hours'); - } - _setupDisplayPlugin() { - if (this.options.displayPlugin === 'docked') - this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions); - if (this.options.displayPlugin === 'modal') { - this.displayPlugin = ModalDisplayPlugin.init(this.el, this.containerEl, { - ...this.options.displayPluginOptions, - ...{ classList: ['timepicker-modal'] } - }); - this.footer.remove(); - this.footer = this.displayPlugin.footer; - } - } - _clockSetup() { - if (this.options.twelveHour) { - // AM Button - this._amBtn = document.createElement('div'); - this._amBtn.classList.add('am-btn', 'btn'); - this._amBtn.innerText = 'AM'; - this._amBtn.tabIndex = 0; - this._amBtn.addEventListener('click', this._handleAmPmClick); - this._amBtn.addEventListener('keypress', this._handleAmPmKeypress); - this.spanAmPm.appendChild(this._amBtn); - // PM Button - this._pmBtn = document.createElement('div'); - this._pmBtn.classList.add('pm-btn', 'btn'); - this._pmBtn.innerText = 'PM'; - this._pmBtn.tabIndex = 0; - this._pmBtn.addEventListener('click', this._handleAmPmClick); - this._pmBtn.addEventListener('keypress', this._handleAmPmKeypress); - this.spanAmPm.appendChild(this._pmBtn); - } - this._buildHoursView(); - this._buildMinutesView(); - this._buildSVGClock(); - } - _buildSVGClock() { - // Draw clock hands and others - const dialRadius = this.options.dialRadius; - const tickRadius = this.options.tickRadius; - const diameter = dialRadius * 2; - const svg = Timepicker._createSVGEl('svg'); - svg.setAttribute('class', 'timepicker-svg'); - svg.setAttribute('width', diameter.toString()); - svg.setAttribute('height', diameter.toString()); - const g = Timepicker._createSVGEl('g'); - g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')'); - const bearing = Timepicker._createSVGEl('circle'); - bearing.setAttribute('class', 'timepicker-canvas-bearing'); - bearing.setAttribute('cx', '0'); - bearing.setAttribute('cy', '0'); - bearing.setAttribute('r', '4'); - const hand = Timepicker._createSVGEl('line'); - hand.setAttribute('x1', '0'); - hand.setAttribute('y1', '0'); - const bg = Timepicker._createSVGEl('circle'); - bg.setAttribute('class', 'timepicker-canvas-bg'); - bg.setAttribute('r', tickRadius.toString()); - g.appendChild(hand); - g.appendChild(bg); - g.appendChild(bearing); - svg.appendChild(g); - this._canvas.appendChild(svg); - this.hand = hand; - this.bg = bg; - this.bearing = bearing; - this.g = g; - } - _buildHoursView() { - // const $tick = document.createElement('div'); - // $tick.classList.add('timepicker-tick'); - // Hours view - if (this.options.twelveHour) { - for (let i = 1; i < 13; i += 1) { - // const tick = $tick.cloneNode(true); - const radian = (i / 6) * Math.PI; - const radius = this.options.outerRadius; - this._buildHoursTick(i, radian, radius); - } - } - else { - for (let i = 0; i < 24; i += 1) { - // const tick = $tick.cloneNode(true); - const radian = (i / 6) * Math.PI; - const inner = i > 0 && i < 13; - const radius = inner ? this.options.innerRadius : this.options.outerRadius; - this._buildHoursTick(i, radian, radius); - } - } - } - _buildHoursTick(i, radian, radius) { - const tick = document.createElement('div'); - tick.classList.add('timepicker-tick'); - tick.style.left = - this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px'; - tick.style.top = - this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px'; - tick.innerHTML = i === 0 ? '00' : i.toString(); - this.hoursView.appendChild(tick); - } - _buildMinutesView() { - const _tick = document.createElement('div'); - _tick.classList.add('timepicker-tick'); - // Minutes view - for (let i = 0; i < 60; i += 5) { - const tick = _tick.cloneNode(true); - const radian = (i / 30) * Math.PI; - tick.style.left = - this.options.dialRadius + - Math.sin(radian) * this.options.outerRadius - - this.options.tickRadius + - 'px'; - tick.style.top = - this.options.dialRadius - - Math.cos(radian) * this.options.outerRadius - - this.options.tickRadius + - 'px'; - tick.innerHTML = Timepicker._addLeadingZero(i); - this.minutesView.appendChild(tick); - } - } - _handleAmPmClick = (e) => { - this._handleAmPmInteraction(e.target); - }; - _handleAmPmKeypress = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleAmPmInteraction(e.target); - } - }; - _handleAmPmInteraction = (e) => { - this.amOrPm = e.classList.contains('am-btn') ? 'AM' : 'PM'; - this._updateAmPmView(); - }; - _updateAmPmView() { - if (this.options.twelveHour) { - if (this.amOrPm === 'PM') { - this._amBtn.classList.remove('filled'); - this._pmBtn.classList.add('filled'); - } - else if (this.amOrPm === 'AM') { - this._amBtn.classList.add('filled'); - this._pmBtn.classList.remove('filled'); - } - } - } - _updateTimeFromInput() { - // Get the time - let value = ((this.el.value || this.options.defaultTime || '') + '').split(':'); - if (this.options.twelveHour && !(typeof value[1] === 'undefined')) { - if (value[1].toUpperCase().indexOf('AM') > 0) { - this.amOrPm = 'AM'; - } - else { - this.amOrPm = 'PM'; - } - value[1] = value[1].replace('AM', '').replace('PM', ''); - } - if (value[0] === 'now') { - const now = new Date(+new Date() + this.options.fromNow); - value = [now.getHours().toString(), now.getMinutes().toString()]; - if (this.options.twelveHour) { - this.amOrPm = parseInt(value[0]) >= 12 && parseInt(value[0]) < 24 ? 'PM' : 'AM'; - } - } - this.hours = +value[0] || 0; - this.minutes = +value[1] || 0; - this.inputHours.value = Timepicker._addLeadingZero(this.hours); - this.inputMinutes.value = Timepicker._addLeadingZero(this.minutes); - this._updateAmPmView(); - } - /** - * Show hours or minutes view on timepicker. - * @param view The name of the view you want to switch to, 'hours' or 'minutes'. - * @param delay - */ - showView = (view, delay = null) => { - if (view === 'minutes' && getComputedStyle(this.hoursView).visibility === 'visible') ; - const isHours = view === 'hours', nextView = isHours ? this.hoursView : this.minutesView, hideView = isHours ? this.minutesView : this.hoursView; - this.currentView = view; - /*if (isHours) { - this.inputHours.classList.add('text-primary'); - this.inputMinutes.classList.remove('text-primary'); - } else { - this.inputHours.classList.remove('text-primary'); - this.inputMinutes.classList.add('text-primary'); - }*/ - // Transition view - hideView.classList.add('timepicker-dial-out'); - nextView.style.visibility = 'visible'; - nextView.classList.remove('timepicker-dial-out'); - // Reset clock hand - this.resetClock(delay); - // After transitions ended - clearTimeout(this.toggleViewTimer); - this.toggleViewTimer = setTimeout(() => { - hideView.style.visibility = 'hidden'; - }, this.options.duration); - }; - resetClock(delay) { - const view = this.currentView, value = this[view], isHours = view === 'hours', unit = Math.PI / (isHours ? 6 : 30), radian = value * unit, radius = isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius, x = Math.sin(radian) * radius, y = -Math.cos(radian) * radius; - if (delay) { - this._canvas?.classList.add('timepicker-canvas-out'); - setTimeout(() => { - this._canvas?.classList.remove('timepicker-canvas-out'); - this.setHand(x, y); - }, delay); - } - else { - this.setHand(x, y); - } - } - _inputFromTextField = () => { - const isHours = this.currentView === 'hours'; - if (isHours && this.inputHours.value !== '') { - const value = parseInt(this.inputHours.value); - if (value > 0 && value < (this.options.twelveHour ? 13 : 24)) { - this.hours = value; - } - else { - this.setHoursDefault(); - } - this.drawClockFromTimeInput(this.hours, isHours); - } - else if (!isHours && this.inputMinutes.value !== '') { - const value = parseInt(this.inputMinutes.value); - if (value >= 0 && value < 60) { - this.minutes = value; - } - else { - this.minutes = new Date().getMinutes(); - this.inputMinutes.value = this.minutes.toString(); - } - this.drawClockFromTimeInput(this.minutes, isHours); - } - }; - drawClockFromTimeInput(value, isHours) { - const unit = Math.PI / (isHours ? 6 : 30); - const radian = value * unit; - let radius; - if (this.options.twelveHour) { - radius = this.options.outerRadius; - } - else { - radius = - isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius; - } - this.setClockAttributes(radian, radius); - } - setHand(x, y, roundBy5 = false) { - const isHours = this.currentView === 'hours', unit = Math.PI / (isHours || roundBy5 ? 6 : 30), z = Math.sqrt(x * x + y * y), inner = isHours && z < (this.options.outerRadius + this.options.innerRadius) / 2; - let radian = Math.atan2(x, -y), radius = inner ? this.options.innerRadius : this.options.outerRadius; - if (this.options.twelveHour) { - radius = this.options.outerRadius; - } - // Radian should in range [0, 2PI] - if (radian < 0) { - radian = Math.PI * 2 + radian; - } - // Get the round value - let value = Math.round(radian / unit); - // Get the round radian - radian = value * unit; - // Correct the hours or minutes - if (this.options.twelveHour) { - if (isHours) { - if (value === 0) - value = 12; - } - else { - if (roundBy5) - value *= 5; - if (value === 60) - value = 0; - } - } - else { - if (isHours) { - if (value === 12) { - value = 0; - } - value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12; - } - else { - if (roundBy5) { - value *= 5; - } - if (value === 60) { - value = 0; - } - } - } - // Once hours or minutes changed, vibrate the device - if (this[this.currentView] !== value) { - if (this.vibrate && this.options.vibrate) { - // Do not vibrate too frequently - if (!this.vibrateTimer) { - navigator[this.vibrate](10); - this.vibrateTimer = setTimeout(() => { - this.vibrateTimer = null; - }, 100); - } - } - } - this[this.currentView] = value; - if (isHours) { - this.inputHours.value = Timepicker._addLeadingZero(value); - } - else { - this.inputMinutes.value = Timepicker._addLeadingZero(value); - } - // Set clock hand and others' position - this.setClockAttributes(radian, radius); - } - setClockAttributes(radian, radius) { - const cx1 = Math.sin(radian) * (radius - this.options.tickRadius), cy1 = -Math.cos(radian) * (radius - this.options.tickRadius), cx2 = Math.sin(radian) * radius, cy2 = -Math.cos(radian) * radius; - this.hand.setAttribute('x2', cx1.toString()); - this.hand.setAttribute('y2', cy1.toString()); - this.bg.setAttribute('cx', cx2.toString()); - this.bg.setAttribute('cy', cy2.toString()); - } - formatHours() { - if (this.inputHours.value == '') - this.setHoursDefault(); - this.inputHours.value = Timepicker._addLeadingZero(Number(this.inputHours.value)); - } - formatMinutes() { - if (this.inputMinutes.value == '') - this.minutes = new Date().getMinutes(); - this.inputMinutes.value = Timepicker._addLeadingZero(Number(this.inputMinutes.value)); - } - setHoursDefault() { - this.hours = new Date().getHours(); - this.inputHours.value = (this.hours % (this.options.twelveHour ? 12 : 24)).toString(); - } - done = (clearValue = null) => { - // Set input value - const last = this.el.value; - let value = clearValue - ? '' - : Timepicker._addLeadingZero(this.hours) + ':' + Timepicker._addLeadingZero(this.minutes); - this.time = value; - if (!clearValue && this.options.twelveHour) { - value = `${value} ${this.amOrPm}`; - } - this.el.value = value; - // Trigger change event - if (value !== last) { - this.el.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); - } - }; - confirm = () => { - this.done(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onDone === 'function') - this.options.onDone.call(this); - }; - cancel = () => { - // not logical clearing the input field on cancel, since the end user might want to make use of the previously submitted value - // this.clear(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onCancel === 'function') - this.options.onCancel.call(this); - }; - clear = () => { - // @todo should clear timepicker hour/minute input elems and reset analog clock, currently clears input el - this.done(true); - }; - // deprecated - open() { - console.warn('Timepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - close() { - console.warn('Timepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - static { - Timepicker._template = `
-
-
-
-
- -
-
- : -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
`; - } - } - - const _defaults$7 = { - text: '', - displayLength: 4000, - inDuration: 300, - outDuration: 375, - classes: '', - completeCallback: null, - activationPercent: 0.8 - }; - class Toast { - /** The toast element. */ - el; - /** - * The remaining amount of time in ms that the toast - * will stay before dismissal. - */ - timeRemaining; - /** - * Describes the current pan state of the Toast. - */ - panning; - options; - message; - counterInterval; - wasSwiped; - startingXPos; - xPos; - time; - deltaX; - velocityX; - static _toasts; - static _container; - static _draggedToast; - constructor(options) { - this.options = { - ...Toast.defaults, - ...options - }; - this.message = this.options.text; - this.panning = false; - this.timeRemaining = this.options.displayLength; - if (Toast._toasts.length === 0) { - Toast._createContainer(); - } - // Create new toast - Toast._toasts.push(this); - const toastElement = this._createToast(); - toastElement['M_Toast'] = this; - this.el = toastElement; - this._animateIn(); - this._setTimer(); - } - static get defaults() { - return _defaults$7; - } - static getInstance(el) { - return el['M_Toast']; - } - static _createContainer() { - const container = document.createElement('div'); - container.setAttribute('id', 'toast-container'); - // Add event handler - container.addEventListener('touchstart', Toast._onDragStart); - container.addEventListener('touchmove', Toast._onDragMove); - container.addEventListener('touchend', Toast._onDragEnd); - container.addEventListener('mousedown', Toast._onDragStart); - document.addEventListener('mousemove', Toast._onDragMove); - document.addEventListener('mouseup', Toast._onDragEnd); - document.body.appendChild(container); - Toast._container = container; - } - static _removeContainer() { - document.removeEventListener('mousemove', Toast._onDragMove); - document.removeEventListener('mouseup', Toast._onDragEnd); - if (Toast._container) { - Toast._container.remove(); - Toast._container = null; - } - } - static _onDragStart(e) { - if (e.target && e.target.closest('.toast')) { - const toastElem = e.target.closest('.toast'); - const toast = toastElem['M_Toast']; - toast.panning = true; - Toast._draggedToast = toast; - toast.el.classList.add('panning'); - toast.el.style.transition = ''; - toast.startingXPos = Toast._xPos(e); - toast.time = Date.now(); - toast.xPos = Toast._xPos(e); - } - } - static _onDragMove(e) { - if (!!Toast._draggedToast) { - e.preventDefault(); - const toast = Toast._draggedToast; - toast.deltaX = Math.abs(toast.xPos - Toast._xPos(e)); - toast.xPos = Toast._xPos(e); - toast.velocityX = toast.deltaX / (Date.now() - toast.time); - toast.time = Date.now(); - const totalDeltaX = toast.xPos - toast.startingXPos; - const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; - toast.el.style.transform = `translateX(${totalDeltaX}px)`; - toast.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString(); - } - } - static _onDragEnd() { - if (!!Toast._draggedToast) { - const toast = Toast._draggedToast; - toast.panning = false; - toast.el.classList.remove('panning'); - const totalDeltaX = toast.xPos - toast.startingXPos; - const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; - const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || toast.velocityX > 1; - // Remove toast - if (shouldBeDismissed) { - toast.wasSwiped = true; - toast.dismiss(); - // Animate toast back to original position - } - else { - toast.el.style.transition = 'transform .2s, opacity .2s'; - toast.el.style.transform = ''; - toast.el.style.opacity = ''; - } - Toast._draggedToast = null; - } - } - static _xPos(e) { - if (e.type.startsWith('touch') && e.targetTouches.length >= 1) { - return e.targetTouches[0].clientX; - } - // mouse event - return e.clientX; - } - /** - * dismiss all toasts. - */ - static dismissAll() { - for (const toastIndex in Toast._toasts) { - Toast._toasts[toastIndex].dismiss(); - } - } - _createToast() { - let toast = this.options.toastId - ? document.getElementById(this.options.toastId) - : document.createElement('div'); - if (toast instanceof HTMLTemplateElement) { - const node = toast.content.cloneNode(true); - toast = node.firstElementChild; - } - toast.classList.add('toast'); - toast.setAttribute('role', 'alert'); - toast.setAttribute('aria-live', 'assertive'); - toast.setAttribute('aria-atomic', 'true'); - // Add custom classes onto toast - if (this.options.classes.length > 0) { - toast.classList.add(...this.options.classes.split(' ')); - } - if (this.message) - toast.innerText = this.message; - if (Toast._container) { - Toast._container.appendChild(toast); - } - return toast; - } - _animateIn() { - // Animate toast in - this.el.style.display = ''; - this.el.style.opacity = '0'; - // easeOutCubic - this.el.style.transition = ` - top ${this.options.inDuration}ms ease, - opacity ${this.options.inDuration}ms ease - `; - setTimeout(() => { - this.el.style.top = '0'; - this.el.style.opacity = '1'; - }, 1); - } - /** - * Create setInterval which automatically removes toast when timeRemaining >= 0 - * has been reached. - */ - _setTimer() { - if (this.timeRemaining !== Infinity) { - this.counterInterval = setInterval(() => { - // If toast is not being dragged, decrease its time remaining - if (!this.panning) { - this.timeRemaining -= 20; - } - // Animate toast out - if (this.timeRemaining <= 0) { - this.dismiss(); - } - }, 20); - } - } - /** - * Dismiss toast with animation. - */ - dismiss() { - clearInterval(this.counterInterval); - const activationDistance = this.el.offsetWidth * this.options.activationPercent; - if (this.wasSwiped) { - this.el.style.transition = 'transform .05s, opacity .05s'; - this.el.style.transform = `translateX(${activationDistance}px)`; - this.el.style.opacity = '0'; - } - // easeOutExpo - this.el.style.transition = ` - margin ${this.options.outDuration}ms ease, - opacity ${this.options.outDuration}ms ease`; - setTimeout(() => { - this.el.style.opacity = '0'; - this.el.style.marginTop = '-40px'; - }, 1); - setTimeout(() => { - // Call the optional callback - if (typeof this.options.completeCallback === 'function') { - this.options.completeCallback(); - } - // Remove toast from DOM - if (this.el.id != this.options.toastId) { - this.el.remove(); - Toast._toasts.splice(Toast._toasts.indexOf(this), 1); - if (Toast._toasts.length === 0) { - Toast._removeContainer(); - } - } - }, this.options.outDuration); - } - static { - Toast._toasts = []; - Toast._container = null; - Toast._draggedToast = null; - } - } - - const _defaults$6 = { - exitDelay: 200, - enterDelay: 0, - text: '', - margin: 5, - inDuration: 250, - outDuration: 200, - position: 'bottom', - transitionMovement: 10, - opacity: 1 - }; - class Tooltip extends Component { - /** - * If tooltip is open. - */ - isOpen; - /** - * If tooltip is hovered. - */ - isHovered; - /** - * If tooltip is focused. - */ - isFocused; - tooltipEl; - _exitDelayTimeout; - _enterDelayTimeout; - xMovement; - yMovement; - constructor(el, options) { - super(el, options, Tooltip); - this.el['M_Tooltip'] = this; - this.options = { - ...Tooltip.defaults, - ...this._getAttributeOptions(), - ...options - }; - this.isOpen = false; - this.isHovered = false; - this.isFocused = false; - this._appendTooltipEl(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$6; - } - /** - * Initializes instances of Tooltip. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Tooltip); - } - static getInstance(el) { - return el['M_Tooltip']; - } - destroy() { - this.tooltipEl.remove(); - this._removeEventHandlers(); - this.el['M_Tooltip'] = undefined; - } - _appendTooltipEl() { - this.tooltipEl = document.createElement('div'); - this.tooltipEl.classList.add('material-tooltip'); - const tooltipContentEl = this.options.tooltipId - ? document.getElementById(this.options.tooltipId) - : document.createElement('div'); - this.tooltipEl.append(tooltipContentEl); - tooltipContentEl.style.display = ''; - tooltipContentEl.classList.add('tooltip-content'); - this._setTooltipContent(tooltipContentEl); - this.tooltipEl.appendChild(tooltipContentEl); - document.body.appendChild(this.tooltipEl); - } - _setTooltipContent(tooltipContentEl) { - if (this.options.tooltipId) - return; - tooltipContentEl.innerText = this.options.text; - } - _updateTooltipContent() { - this._setTooltipContent(this.tooltipEl.querySelector('.tooltip-content')); - } - _setupEventHandlers() { - this.el.addEventListener('mouseenter', this._handleMouseEnter); - this.el.addEventListener('mouseleave', this._handleMouseLeave); - this.el.addEventListener('focus', this._handleFocus, true); - this.el.addEventListener('blur', this._handleBlur, true); - } - _removeEventHandlers() { - this.el.removeEventListener('mouseenter', this._handleMouseEnter); - this.el.removeEventListener('mouseleave', this._handleMouseLeave); - this.el.removeEventListener('focus', this._handleFocus, true); - this.el.removeEventListener('blur', this._handleBlur, true); - } - /** - * Show tooltip. - */ - open = (isManual) => { - if (this.isOpen) - return; - isManual = isManual === undefined ? true : undefined; // Default value true - this.isOpen = true; - // Update tooltip content with HTML attribute options - this.options = { ...this.options, ...this._getAttributeOptions() }; - this._updateTooltipContent(); - this._setEnterDelayTimeout(isManual); - }; - /** - * Hide tooltip. - */ - close = () => { - if (!this.isOpen) - return; - this.isHovered = false; - this.isFocused = false; - this.isOpen = false; - this._setExitDelayTimeout(); - }; - _setExitDelayTimeout() { - clearTimeout(this._exitDelayTimeout); - this._exitDelayTimeout = setTimeout(() => { - if (this.isHovered || this.isFocused) - return; - this._animateOut(); - }, this.options.exitDelay); - } - _setEnterDelayTimeout(isManual) { - clearTimeout(this._enterDelayTimeout); - this._enterDelayTimeout = setTimeout(() => { - if (!this.isHovered && !this.isFocused && !isManual) - return; - this._animateIn(); - }, this.options.enterDelay); - } - _positionTooltip() { - const tooltip = this.tooltipEl; - const origin = this.el, originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, tooltipHeight = tooltip.offsetHeight, tooltipWidth = tooltip.offsetWidth, margin = this.options.margin; - this.xMovement = 0; - this.yMovement = 0; - let targetTop = origin.getBoundingClientRect().top + Utils.getDocumentScrollTop(); - let targetLeft = origin.getBoundingClientRect().left + Utils.getDocumentScrollLeft(); - if (this.options.position === 'top') { - targetTop += -tooltipHeight - margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = -this.options.transitionMovement; - } - else if (this.options.position === 'right') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += originWidth + margin; - this.xMovement = this.options.transitionMovement; - } - else if (this.options.position === 'left') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += -tooltipWidth - margin; - this.xMovement = -this.options.transitionMovement; - } - else { - targetTop += originHeight + margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = this.options.transitionMovement; - } - const newCoordinates = this._repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); - tooltip.style.top = newCoordinates.y + 'px'; - tooltip.style.left = newCoordinates.x + 'px'; - } - _repositionWithinScreen(x, y, width, height) { - const scrollLeft = Utils.getDocumentScrollLeft(); - const scrollTop = Utils.getDocumentScrollTop(); - let newX = x - scrollLeft; - let newY = y - scrollTop; - const bounding = { - left: newX, - top: newY, - width: width, - height: height - }; - const offset = this.options.margin + this.options.transitionMovement; - const edges = Utils.checkWithinContainer(document.body, bounding, offset); - if (edges.left) { - newX = offset; - } - else if (edges.right) { - newX -= newX + width - window.innerWidth; - } - if (edges.top) { - newY = offset; - } - else if (edges.bottom) { - newY -= newY + height - window.innerHeight; - } - return { - x: newX + scrollLeft, - y: newY + scrollTop - }; - } - _animateIn() { - this._positionTooltip(); - this.tooltipEl.style.visibility = 'visible'; - const duration = this.options.inDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`; - this.tooltipEl.style.opacity = (this.options.opacity || 1).toString(); - }, 1); - } - _animateOut() { - const duration = this.options.outDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`; - this.tooltipEl.style.opacity = '0'; - }, 1); - /* - anim.remove(this.tooltipEl); - anim({ - targets: this.tooltipEl, - opacity: 0, - translateX: 0, - translateY: 0, - duration: this.options.outDuration, - easing: 'easeOutCubic' - }); - */ - } - _handleMouseEnter = () => { - this.isHovered = true; - this.isFocused = false; // Allows close of tooltip when opened by focus. - this.open(false); - }; - _handleMouseLeave = () => { - this.isHovered = false; - this.isFocused = false; // Allows close of tooltip when opened by focus. - this.close(); - }; - _handleFocus = () => { - if (Utils.tabPressed) { - this.isFocused = true; - this.open(false); - } - }; - _handleBlur = () => { - this.isFocused = false; - this.close(); - }; - _getAttributeOptions() { - const attributeOptions = {}; - const tooltipTextOption = this.el.getAttribute('data-tooltip'); - const tooltipId = this.el.getAttribute('data-tooltip-id'); - const positionOption = this.el.getAttribute('data-position'); - if (tooltipTextOption) { - attributeOptions.text = tooltipTextOption; - } - if (positionOption) { - attributeOptions.position = positionOption; - } - if (tooltipId) { - attributeOptions.tooltipId = tooltipId; - } - return attributeOptions; - } - } - - const _defaults$5 = {}; - // TODO: !!!!! - class Range extends Component { - _mousedown; - value; - thumb; - constructor(el, options) { - super(el, options, Range); - this.el['M_Range'] = this; - this.options = { - ...Range.defaults, - ...options - }; - this._mousedown = false; - this._setupThumb(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$5; - } - /** - * Initializes instances of Range. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Range); - } - static getInstance(el) { - return el['M_Range']; - } - destroy() { - this._removeEventHandlers(); - this._removeThumb(); - this.el['M_Range'] = undefined; - } - _setupEventHandlers() { - this.el.addEventListener('change', this._handleRangeChange); - this.el.addEventListener('mousedown', this._handleRangeMousedownTouchstart); - this.el.addEventListener('touchstart', this._handleRangeMousedownTouchstart); - this.el.addEventListener('input', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('mousemove', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('touchmove', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('mouseup', this._handleRangeMouseupTouchend); - this.el.addEventListener('touchend', this._handleRangeMouseupTouchend); - this.el.addEventListener('blur', this._handleRangeBlurMouseoutTouchleave); - this.el.addEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave); - this.el.addEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave); - } - _removeEventHandlers() { - this.el.removeEventListener('change', this._handleRangeChange); - this.el.removeEventListener('mousedown', this._handleRangeMousedownTouchstart); - this.el.removeEventListener('touchstart', this._handleRangeMousedownTouchstart); - this.el.removeEventListener('input', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('mousemove', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('touchmove', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('mouseup', this._handleRangeMouseupTouchend); - this.el.removeEventListener('touchend', this._handleRangeMouseupTouchend); - this.el.removeEventListener('blur', this._handleRangeBlurMouseoutTouchleave); - this.el.removeEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave); - this.el.removeEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave); - } - _handleRangeChange = () => { - this.value.innerHTML = this.el.value; - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - }; - _handleRangeMousedownTouchstart = (e) => { - // Set indicator value - this.value.innerHTML = this.el.value; - this._mousedown = true; - this.el.classList.add('active'); - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - if (e.type !== 'input') { - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - } - }; - _handleRangeInputMousemoveTouchmove = () => { - if (this._mousedown) { - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - this.value.innerHTML = this.el.value; - } - }; - _handleRangeMouseupTouchend = () => { - this._mousedown = false; - this.el.classList.remove('active'); - }; - _handleRangeBlurMouseoutTouchleave = () => { - if (!this._mousedown) { - const paddingLeft = parseInt(getComputedStyle(this.el).paddingLeft); - const marginLeftText = 7 + paddingLeft + 'px'; - if (this.thumb.classList.contains('active')) { - const duration = 100; - // from - this.thumb.style.transition = 'none'; - setTimeout(() => { - this.thumb.style.transition = ` - height ${duration}ms ease, - width ${duration}ms ease, - top ${duration}ms ease, - margin ${duration}ms ease - `; - // to - this.thumb.style.height = '0'; - this.thumb.style.width = '0'; - this.thumb.style.top = '0'; - this.thumb.style.marginLeft = marginLeftText; - }, 1); - } - this.thumb.classList.remove('active'); - } - }; - _setupThumb() { - this.thumb = document.createElement('span'); - this.value = document.createElement('span'); - this.thumb.classList.add('thumb'); - this.value.classList.add('value'); - this.thumb.append(this.value); - this.el.after(this.thumb); - } - _removeThumb() { - this.thumb.remove(); - } - _showRangeBubble() { - const paddingLeft = parseInt(getComputedStyle(this.thumb.parentElement).paddingLeft); - const marginLeftText = -7 + paddingLeft + 'px'; // TODO: fix magic number? - const duration = 300; - // easeOutQuint - this.thumb.style.transition = ` - height ${duration}ms ease, - width ${duration}ms ease, - top ${duration}ms ease, - margin ${duration}ms ease - `; - // to - this.thumb.style.height = '30px'; - this.thumb.style.width = '30px'; - this.thumb.style.top = '-30px'; - this.thumb.style.marginLeft = marginLeftText; - } - _calcRangeOffset() { - const width = this.el.getBoundingClientRect().width - 15; - const max = parseFloat(this.el.getAttribute('max')) || 100; // Range default max - const min = parseFloat(this.el.getAttribute('min')) || 0; // Range default min - const percent = (parseFloat(this.el.value) - min) / (max - min); - return percent * width; - } - /** - * Initializes every range input in the current document. - */ - static Init() { - if (typeof document !== 'undefined') - Range.init(document?.querySelectorAll('input[type=range]'), {}); - } - } - - const _defaults$4 = { - onOpen: null, - onClose: null - }; - class TapTarget extends Component { - /** - * If the tap target is open. - */ - isOpen; - static _taptargets; - wrapper; - // private _origin: HTMLElement; - originEl; - waveEl; - contentEl; - constructor(el, options) { - super(el, options, TapTarget); - this.el['M_TapTarget'] = this; - this.options = { - ...TapTarget.defaults, - ...options - }; - this.isOpen = false; - // setup - this.originEl = document.querySelector(`#${el.dataset.target}`); - this.originEl.tabIndex = 0; - this._setup(); - this._calculatePositioning(); - this._setupEventHandlers(); - TapTarget._taptargets.push(this); - } - static get defaults() { - return _defaults$4; - } - /** - * Initializes instances of TapTarget. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, TapTarget); - } - static getInstance(el) { - return el['M_TapTarget']; - } - destroy() { - this._removeEventHandlers(); - this.el['M_TapTarget'] = undefined; - const index = TapTarget._taptargets.indexOf(this); - if (index >= 0) { - TapTarget._taptargets.splice(index, 1); - } - } - _setupEventHandlers() { - this.originEl.addEventListener('click', this._handleTargetToggle); - this.originEl.addEventListener('keypress', this._handleKeyboardInteraction, true); - // this.originEl.addEventListener('click', this._handleOriginClick); - // Resize - window.addEventListener('resize', this._handleThrottledResize); - } - _removeEventHandlers() { - this.originEl.removeEventListener('click', this._handleTargetToggle); - this.originEl.removeEventListener('keypress', this._handleKeyboardInteraction, true); - // this.originEl.removeEventListener('click', this._handleOriginClick); - window.removeEventListener('resize', this._handleThrottledResize); - } - _handleThrottledResize = () => Utils.throttle(this._handleResize, 200).bind(this); - _handleKeyboardInteraction = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleTargetToggle(); - } - }; - _handleTargetToggle = () => { - if (!this.isOpen) - this.open(); - else - this.close(); - }; - /*_handleOriginClick = () => { - this.close(); - }*/ - _handleResize = () => { - this._calculatePositioning(); - }; - _handleDocumentClick = (e) => { - if (e.target.closest(`#${this.el.dataset.target}`) !== this.originEl && - !e.target.closest('.tap-target-wrapper')) { - this.close(); - // e.preventDefault(); - // e.stopPropagation(); - } - }; - _setup() { - // Creating tap target - this.wrapper = this.el.parentElement; - this.waveEl = this.wrapper.querySelector('.tap-target-wave'); - this.el.parentElement.ariaExpanded = 'false'; - this.originEl.style.zIndex = '1002'; - // this.originEl = this.wrapper.querySelector('.tap-target-origin'); - this.contentEl = this.el.querySelector('.tap-target-content'); - // Creating wrapper - if (!this.wrapper.classList.contains('.tap-target-wrapper')) { - this.wrapper = document.createElement('div'); - this.wrapper.classList.add('tap-target-wrapper'); - this.el.before(this.wrapper); - this.wrapper.append(this.el); - } - // Creating content - if (!this.contentEl) { - this.contentEl = document.createElement('div'); - this.contentEl.classList.add('tap-target-content'); - this.el.append(this.contentEl); - } - // Creating foreground wave - if (!this.waveEl) { - this.waveEl = document.createElement('div'); - this.waveEl.classList.add('tap-target-wave'); - // Creating origin - /*if (!this.originEl) { - this.originEl = this._origin.cloneNode(true); // .clone(true, true); - this.originEl.classList.add('tap-target-origin'); - this.originEl.removeAttribute('id'); - this.originEl.removeAttribute('style'); - this.waveEl.append(this.originEl); - }*/ - this.wrapper.append(this.waveEl); - } - } - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - _calculatePositioning() { - // Element or parent is fixed position? - let isFixed = getComputedStyle(this.originEl).position === 'fixed'; - if (!isFixed) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let currentElem = this.originEl; - const parents = []; - while ((currentElem = currentElem.parentNode) && currentElem !== document) - parents.push(currentElem); - for (let i = 0; i < parents.length; i++) { - isFixed = getComputedStyle(parents[i]).position === 'fixed'; - if (isFixed) - break; - } - } - // Calculating origin - const originWidth = this.originEl.offsetWidth; - const originHeight = this.originEl.offsetHeight; - const originTop = isFixed - ? this._offset(this.originEl).top - Utils.getDocumentScrollTop() - : this._offset(this.originEl).top; - const originLeft = isFixed - ? this._offset(this.originEl).left - Utils.getDocumentScrollLeft() - : this._offset(this.originEl).left; - // Calculating screen - const windowWidth = window.innerWidth; - const windowHeight = window.innerHeight; - const scrollBarWidth = windowWidth - document.documentElement.clientWidth; - const centerX = windowWidth / 2; - const centerY = windowHeight / 2; - const isLeft = originLeft <= centerX; - const isRight = originLeft > centerX; - const isTop = originTop <= centerY; - const isBottom = originTop > centerY; - const isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75; - // Calculating tap target - const tapTargetWidth = this.el.offsetWidth; - const tapTargetHeight = this.el.offsetHeight; - const tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2; - const tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2; - const tapTargetPosition = isFixed ? 'fixed' : 'absolute'; - // Calculating content - const tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth; - const tapTargetTextHeight = tapTargetHeight / 2; - const tapTargetTextTop = isTop ? tapTargetHeight / 2 : 0; - const tapTargetTextBottom = 0; - const tapTargetTextLeft = isLeft && !isCenterX ? tapTargetWidth / 2 - originWidth : 0; - const tapTargetTextRight = 0; - const tapTargetTextPadding = originWidth; - const tapTargetTextAlign = isBottom ? 'bottom' : 'top'; - // Calculating wave - const tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2; - const tapTargetWaveHeight = tapTargetWaveWidth; - const tapTargetWaveTop = tapTargetHeight / 2 - tapTargetWaveHeight / 2; - const tapTargetWaveLeft = tapTargetWidth / 2 - tapTargetWaveWidth / 2; - // Setting tap target - this.wrapper.style.top = isTop ? tapTargetTop + 'px' : ''; - this.wrapper.style.right = isRight - ? windowWidth - tapTargetLeft - tapTargetWidth - scrollBarWidth + 'px' - : ''; - this.wrapper.style.bottom = isBottom - ? windowHeight - tapTargetTop - tapTargetHeight + 'px' - : ''; - this.wrapper.style.left = isLeft ? tapTargetLeft + 'px' : ''; - this.wrapper.style.position = tapTargetPosition; - // Setting content - this.contentEl.style.width = tapTargetTextWidth + 'px'; - this.contentEl.style.height = tapTargetTextHeight + 'px'; - this.contentEl.style.top = tapTargetTextTop + 'px'; - this.contentEl.style.right = tapTargetTextRight + 'px'; - this.contentEl.style.bottom = tapTargetTextBottom + 'px'; - this.contentEl.style.left = tapTargetTextLeft + 'px'; - this.contentEl.style.padding = tapTargetTextPadding + 'px'; - this.contentEl.style.verticalAlign = tapTargetTextAlign; - // Setting wave - this.waveEl.style.top = tapTargetWaveTop + 'px'; - this.waveEl.style.left = tapTargetWaveLeft + 'px'; - this.waveEl.style.width = tapTargetWaveWidth + 'px'; - this.waveEl.style.height = tapTargetWaveHeight + 'px'; - } - /** - * Open Tap Target. - */ - open = () => { - if (this.isOpen) - return; - // onOpen callback - if (typeof this.options.onOpen === 'function') { - this.options.onOpen.call(this, this.originEl); - } - this.isOpen = true; - this.wrapper.classList.add('open'); - this.wrapper.ariaExpanded = 'true'; - document.body.addEventListener('click', this._handleDocumentClick, true); - document.body.addEventListener('keypress', this._handleDocumentClick, true); - document.body.addEventListener('touchend', this._handleDocumentClick); - }; - /** - * Close Tap Target. - */ - close = () => { - if (!this.isOpen) - return; - // onClose callback - if (typeof this.options.onClose === 'function') { - this.options.onClose.call(this, this.originEl); - } - this.isOpen = false; - this.wrapper.classList.remove('open'); - this.wrapper.ariaExpanded = 'false'; - document.body.removeEventListener('click', this._handleDocumentClick, true); - document.body.removeEventListener('keypress', this._handleDocumentClick, true); - document.body.removeEventListener('touchend', this._handleDocumentClick); - }; - static { - TapTarget._taptargets = []; - } - } - - const _defaults$3 = Object.freeze({}); - class CharacterCounter extends Component { - /** Stores the reference to the counter HTML element. */ - counterEl; - /** Specifies whether the input is valid or not. */ - isInvalid; - /** Specifies whether the input text has valid length or not. */ - isValidLength; - constructor(el, options) { - super(el, {}, CharacterCounter); - this.el['M_CharacterCounter'] = this; - this.options = { - ...CharacterCounter.defaults, - ...options - }; - this.isInvalid = false; - this.isValidLength = false; - this._setupCounter(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$3; - } - /** - * Initializes instances of CharacterCounter. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, CharacterCounter); - } - static getInstance(el) { - return el['M_CharacterCounter']; - } - destroy() { - this._removeEventHandlers(); - this.el['CharacterCounter'] = undefined; - this._removeCounter(); - } - _setupEventHandlers() { - this.el.addEventListener('focus', this.updateCounter, true); - this.el.addEventListener('input', this.updateCounter, true); - } - _removeEventHandlers() { - this.el.removeEventListener('focus', this.updateCounter, true); - this.el.removeEventListener('input', this.updateCounter, true); - } - _setupCounter() { - this.counterEl = document.createElement('span'); - this.counterEl.classList.add('character-counter'); - this.counterEl.style.float = 'right'; - this.counterEl.style.fontSize = '12px'; - this.counterEl.style.height = '1'; - this.el.parentElement.appendChild(this.counterEl); - } - _removeCounter() { - this.counterEl.remove(); - } - updateCounter = () => { - const maxLength = parseInt(this.el.getAttribute('maxlength')), actualLength = this.el.value.length; - this.isValidLength = actualLength <= maxLength; - let counterString = actualLength.toString(); - if (maxLength) { - counterString += '/' + maxLength; - this._validateInput(); - } - this.counterEl.innerHTML = counterString; - }; - _validateInput() { - if (this.isValidLength && this.isInvalid) { - this.isInvalid = false; - this.el.classList.remove('invalid'); - } - else if (!this.isValidLength && !this.isInvalid) { - this.isInvalid = true; - this.el.classList.remove('valid'); - this.el.classList.add('invalid'); - } - } - } - - const _defaults$2 = { - responsiveThreshold: 0 // breakpoint for swipeable - }; - class Parallax extends Component { - _enabled; - _img; - static _parallaxes = []; - static _handleScrollThrottled; - static _handleWindowResizeThrottled; - constructor(el, options) { - super(el, options, Parallax); - this.el['M_Parallax'] = this; - this.options = { - ...Parallax.defaults, - ...options - }; - this._enabled = window.innerWidth > this.options.responsiveThreshold; - this._img = this.el.querySelector('img'); - this._updateParallax(); - this._setupEventHandlers(); - this._setupStyles(); - Parallax._parallaxes.push(this); - } - static get defaults() { - return _defaults$2; - } - /** - * Initializes instances of Parallax. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Parallax); - } - static getInstance(el) { - return el['M_Parallax']; - } - destroy() { - Parallax._parallaxes.splice(Parallax._parallaxes.indexOf(this), 1); - this._img.style.transform = ''; - this._removeEventHandlers(); - this.el['M_Parallax'] = undefined; - } - static _handleScroll() { - for (let i = 0; i < Parallax._parallaxes.length; i++) { - const parallaxInstance = Parallax._parallaxes[i]; - parallaxInstance._updateParallax.call(parallaxInstance); - } - } - static _handleWindowResize() { - for (let i = 0; i < Parallax._parallaxes.length; i++) { - const parallaxInstance = Parallax._parallaxes[i]; - parallaxInstance._enabled = window.innerWidth > parallaxInstance.options.responsiveThreshold; - } - } - _setupEventHandlers() { - this._img.addEventListener('load', this._handleImageLoad); - if (Parallax._parallaxes.length === 0) { - if (!Parallax._handleScrollThrottled) { - Parallax._handleScrollThrottled = Utils.throttle(Parallax._handleScroll, 5); - } - if (!Parallax._handleWindowResizeThrottled) { - Parallax._handleWindowResizeThrottled = Utils.throttle(Parallax._handleWindowResize, 5); - } - window.addEventListener('scroll', Parallax._handleScrollThrottled); - window.addEventListener('resize', Parallax._handleWindowResizeThrottled); - } - } - _removeEventHandlers() { - this._img.removeEventListener('load', this._handleImageLoad); - if (Parallax._parallaxes.length === 0) { - window.removeEventListener('scroll', Parallax._handleScrollThrottled); - window.removeEventListener('resize', Parallax._handleWindowResizeThrottled); - } - } - _setupStyles() { - this._img.style.opacity = '1'; - } - _handleImageLoad = () => { - this._updateParallax(); - }; - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.scrollY - docElem.clientTop, - left: box.left + window.scrollX - docElem.clientLeft - }; - } - _updateParallax() { - const containerHeight = this.el.getBoundingClientRect().height > 0 ? this.el.parentElement.offsetHeight : 500; - const imgHeight = this._img.offsetHeight; - const parallaxDist = imgHeight - containerHeight; - const bottom = this._offset(this.el).top + containerHeight; - const top = this._offset(this.el).top; - const scrollTop = Utils.getDocumentScrollTop(); - const windowHeight = window.innerHeight; - const windowBottom = scrollTop + windowHeight; - const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight); - const parallax = parallaxDist * percentScrolled; - if (!this._enabled) { - this._img.style.transform = ''; - } - else if (bottom > scrollTop && top < scrollTop + windowHeight) { - this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`; - } - } - } - - const _defaults$1 = { - top: 0, - bottom: Infinity, - offset: 0, - onPositionChange: null - }; - class Pushpin extends Component { - static _pushpins; - originalOffset; - constructor(el, options) { - super(el, options, Pushpin); - this.el['M_Pushpin'] = this; - this.options = { - ...Pushpin.defaults, - ...options - }; - this.originalOffset = this.el.offsetTop; - Pushpin._pushpins.push(this); - this._setupEventHandlers(); - this._updatePosition(); - } - static get defaults() { - return _defaults$1; - } - /** - * Initializes instances of Pushpin. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Pushpin); - } - static getInstance(el) { - return el['M_Pushpin']; - } - destroy() { - this.el.style.top = null; - this._removePinClasses(); - // Remove pushpin Inst - const index = Pushpin._pushpins.indexOf(this); - Pushpin._pushpins.splice(index, 1); - if (Pushpin._pushpins.length === 0) { - this._removeEventHandlers(); - } - this.el['M_Pushpin'] = undefined; - } - static _updateElements() { - for (const elIndex in Pushpin._pushpins) { - const pInstance = Pushpin._pushpins[elIndex]; - pInstance._updatePosition(); - } - } - _setupEventHandlers() { - document.addEventListener('scroll', Pushpin._updateElements); - } - _removeEventHandlers() { - document.removeEventListener('scroll', Pushpin._updateElements); - } - _updatePosition() { - const scrolled = Utils.getDocumentScrollTop() + this.options.offset; - if (this.options.top <= scrolled && - this.options.bottom >= scrolled && - !this.el.classList.contains('pinned')) { - this._removePinClasses(); - this.el.style.top = `${this.options.offset}px`; - this.el.classList.add('pinned'); - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pinned'); - } - } - // Add pin-top (when scrolled position is above top) - if (scrolled < this.options.top && !this.el.classList.contains('pin-top')) { - this._removePinClasses(); - this.el.style.top = '0'; - this.el.classList.add('pin-top'); - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pin-top'); - } - } - // Add pin-bottom (when scrolled position is below bottom) - if (scrolled > this.options.bottom && !this.el.classList.contains('pin-bottom')) { - this._removePinClasses(); - this.el.classList.add('pin-bottom'); - this.el.style.top = `${this.options.bottom - this.originalOffset}px`; - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pin-bottom'); - } - } - } - _removePinClasses() { - // IE 11 bug (can't remove multiple classes in one line) - this.el.classList.remove('pin-top'); - this.el.classList.remove('pinned'); - this.el.classList.remove('pin-bottom'); - } - static { - Pushpin._pushpins = []; - } - } - - const _defaults = { - throttle: 100, - scrollOffset: 200, // offset - 200 allows elements near bottom of page to scroll - activeClass: 'active', - getActiveElement: (id) => { - return 'a[href="#' + id + '"]'; - }, - keepTopElementActive: false, - animationDuration: null - }; - class ScrollSpy extends Component { - static _elements; - static _count; - static _increment; - static _elementsInView; - static _visibleElements; - static _ticks; - static _keptTopActiveElement = null; - tickId; - id; - constructor(el, options) { - super(el, options, ScrollSpy); - this.el['M_ScrollSpy'] = this; - this.options = { - ...ScrollSpy.defaults, - ...options - }; - ScrollSpy._elements.push(this); - ScrollSpy._count++; - ScrollSpy._increment++; - this.tickId = -1; - this.id = ScrollSpy._increment.toString(); - this._setupEventHandlers(); - this._handleWindowScroll(); - } - static get defaults() { - return _defaults; - } - /** - * Initializes instances of ScrollSpy. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, ScrollSpy); - } - static getInstance(el) { - return el['M_ScrollSpy']; - } - destroy() { - ScrollSpy._elements.splice(ScrollSpy._elements.indexOf(this), 1); - ScrollSpy._elementsInView.splice(ScrollSpy._elementsInView.indexOf(this), 1); - ScrollSpy._visibleElements.splice(ScrollSpy._visibleElements.indexOf(this.el), 1); - ScrollSpy._count--; - this._removeEventHandlers(); - const actElem = document.querySelector(this.options.getActiveElement(this.el.id)); - actElem.classList.remove(this.options.activeClass); - this.el['M_ScrollSpy'] = undefined; - } - _setupEventHandlers() { - if (ScrollSpy._count === 1) { - window.addEventListener('scroll', this._handleWindowScroll); - window.addEventListener('resize', this._handleThrottledResize); - document.body.addEventListener('click', this._handleTriggerClick); - } - } - _removeEventHandlers() { - if (ScrollSpy._count === 0) { - window.removeEventListener('scroll', this._handleWindowScroll); - window.removeEventListener('resize', this._handleThrottledResize); - document.body.removeEventListener('click', this._handleTriggerClick); - } - } - _handleThrottledResize = () => Utils.throttle(this._handleWindowScroll, 200).bind(this); - _handleTriggerClick = (e) => { - const trigger = e.target; - for (let i = ScrollSpy._elements.length - 1; i >= 0; i--) { - const scrollspy = ScrollSpy._elements[i]; - const x = document.querySelector('a[href="#' + scrollspy.el.id + '"]'); - if (trigger === x) { - e.preventDefault(); - if (scrollspy.el['M_ScrollSpy'].options.animationDuration) { - ScrollSpy._smoothScrollIntoView(scrollspy.el, scrollspy.el['M_ScrollSpy'].options.animationDuration); - } - else { - scrollspy.el.scrollIntoView({ behavior: 'smooth' }); - } - break; - } - } - }; - _handleWindowScroll = () => { - // unique tick id - ScrollSpy._ticks++; - // viewport rectangle - const top = Utils.getDocumentScrollTop(), left = Utils.getDocumentScrollLeft(), right = left + window.innerWidth, bottom = top + window.innerHeight; - // determine which elements are in view - const intersections = ScrollSpy._findElements(top, right, bottom, left); - for (let i = 0; i < intersections.length; i++) { - const scrollspy = intersections[i]; - const lastTick = scrollspy.tickId; - if (lastTick < 0) { - // entered into view - scrollspy._enter(); - } - // update tick id - scrollspy.tickId = ScrollSpy._ticks; - } - for (let i = 0; i < ScrollSpy._elementsInView.length; i++) { - const scrollspy = ScrollSpy._elementsInView[i]; - const lastTick = scrollspy.tickId; - if (lastTick >= 0 && lastTick !== ScrollSpy._ticks) { - // exited from view - scrollspy._exit(); - scrollspy.tickId = -1; - } - } - // remember elements in view for next tick - ScrollSpy._elementsInView = intersections; - if (ScrollSpy._elements.length) { - const options = ScrollSpy._elements[0].el['M_ScrollSpy'].options; - if (options.keepTopElementActive && ScrollSpy._visibleElements.length === 0) { - this._resetKeptTopActiveElementIfNeeded(); - const topElements = ScrollSpy._elements - .filter((value) => ScrollSpy._getDistanceToViewport(value.el) <= 0) - .sort((a, b) => { - const distanceA = ScrollSpy._getDistanceToViewport(a.el); - const distanceB = ScrollSpy._getDistanceToViewport(b.el); - if (distanceA < distanceB) - return -1; - if (distanceA > distanceB) - return 1; - return 0; - }); - const nearestTopElement = topElements.length - ? topElements[topElements.length - 1] - : ScrollSpy._elements[0]; - const actElem = document.querySelector(options.getActiveElement(nearestTopElement.el.id)); - actElem?.classList.add(options.activeClass); - ScrollSpy._keptTopActiveElement = actElem; - } - } - }; - static _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - static _findElements(top, right, bottom, left) { - const hits = []; - for (let i = 0; i < ScrollSpy._elements.length; i++) { - const scrollspy = ScrollSpy._elements[i]; - const currTop = top + scrollspy.options.scrollOffset || 200; - if (scrollspy.el.getBoundingClientRect().height > 0) { - const elTop = ScrollSpy._offset(scrollspy.el).top, elLeft = ScrollSpy._offset(scrollspy.el).left, elRight = elLeft + scrollspy.el.getBoundingClientRect().width, elBottom = elTop + scrollspy.el.getBoundingClientRect().height; - const isIntersect = !(elLeft > right || - elRight < left || - elTop > bottom || - elBottom < currTop); - if (isIntersect) { - hits.push(scrollspy); - } - } - } - return hits; - } - _enter() { - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((value) => value.getBoundingClientRect().height !== 0); - if (ScrollSpy._visibleElements[0]) { - const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id)); - actElem?.classList.remove(this.options.activeClass); - if (ScrollSpy._visibleElements[0]['M_ScrollSpy'] && - this.id < ScrollSpy._visibleElements[0]['M_ScrollSpy'].id) { - ScrollSpy._visibleElements.unshift(this.el); - } - else { - ScrollSpy._visibleElements.push(this.el); - } - } - else { - ScrollSpy._visibleElements.push(this.el); - } - this._resetKeptTopActiveElementIfNeeded(); - const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id); - document.querySelector(selector)?.classList.add(this.options.activeClass); - } - _exit() { - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((value) => value.getBoundingClientRect().height !== 0); - if (ScrollSpy._visibleElements[0]) { - const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id)); - actElem?.classList.remove(this.options.activeClass); - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((x) => x.id != this.el.id); - if (ScrollSpy._visibleElements[0]) { - // Check if empty - const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id); - document.querySelector(selector)?.classList.add(this.options.activeClass); - this._resetKeptTopActiveElementIfNeeded(); - } - } - } - _resetKeptTopActiveElementIfNeeded() { - if (ScrollSpy._keptTopActiveElement) { - ScrollSpy._keptTopActiveElement.classList.remove(this.options.activeClass); - ScrollSpy._keptTopActiveElement = null; - } - } - static _getDistanceToViewport(element) { - const rect = element.getBoundingClientRect(); - const distance = rect.top; - return distance; - } - static _smoothScrollIntoView(element, duration = 300) { - const targetPosition = element.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); - const startPosition = window.scrollY || window.pageYOffset; - const distance = targetPosition - startPosition; - const startTime = performance.now(); - function scrollStep(currentTime) { - const elapsed = currentTime - startTime; - const progress = Math.min(elapsed / duration, 1); - const scrollY = startPosition + distance * progress; - if (progress < 1) { - window.scrollTo(0, scrollY); - requestAnimationFrame(scrollStep); - } - else { - window.scrollTo(0, targetPosition); - } - } - requestAnimationFrame(scrollStep); - } - static { - ScrollSpy._elements = []; - ScrollSpy._elementsInView = []; - ScrollSpy._visibleElements = []; // Array. - ScrollSpy._count = 0; - ScrollSpy._increment = 0; - ScrollSpy._ticks = 0; - } - } - - // type RGBColor = { - // r: number; - // g: number; - // b: number; - // }; - - // type Position = { - // x: number; - // y: number; - // }; - - class Waves { - /** - * - * @param {HTMLElement} el - * @returns - */ - static #offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - - // https://phoenix-dx.com/css-techniques-for-material-ripple-effect/ - - /** - * - * @param {HTMLElement} targetElement - * @param position - * @param color - */ - static renderWaveEffect(targetElement, position = null, color = null) { - const isCentered = position === null; - const duration = 500; - let animationFrame, animationStart; - - const animationStep = (timestamp) => { - if (!animationStart) animationStart = timestamp; - const frame = timestamp - animationStart; - if (frame < duration) { - const easing = (frame / duration) * (2 - frame / duration); - const circle = isCentered - ? 'circle at 50% 50%' - : `circle at ${position.x}px ${position.y}px`; - const waveColor = `rgba(${color?.r || 0}, ${color?.g || 0}, ${color?.b || 0}, ${0.3 * (1 - easing)})`; - const stop = 90 * easing + '%'; - targetElement.style.backgroundImage = - 'radial-gradient(' + - circle + - ', ' + - waveColor + - ' ' + - stop + - ', transparent ' + - stop + - ')'; - animationFrame = window.requestAnimationFrame(animationStep); - } else { - targetElement.style.backgroundImage = 'none'; - window.cancelAnimationFrame(animationFrame); - } - }; - - animationFrame = window.requestAnimationFrame(animationStep); - } - - static Init() { - if (typeof document !== 'undefined') - document?.addEventListener('DOMContentLoaded', () => { - document.body.addEventListener('click', (e) => { - const trigger = e.target; - const el = trigger.closest('.waves-effect'); - if (el && el.contains(trigger)) { - const isCircular = el.classList.contains('waves-circle'); - const x = e.pageX - this.#offset(el).left; - const y = e.pageY - this.#offset(el).top; - let color = null; - if (el.classList.contains('waves-light')) color = { r: 255, g: 255, b: 255 }; - this.renderWaveEffect(el, isCircular ? null : { x, y }, color); - } - }); - }); - } - } - - /* eslint-disable @typescript-eslint/no-unused-vars */ - const version = '2.3.3'; - /** - * Automatically initialize components. - * @param context Root element to initialize. Defaults to `document.body`. - * @param options Options for each component. - */ - function AutoInit(context = document.body, options) { - const registry = { - Autocomplete: context.querySelectorAll('.autocomplete:not(.no-autoinit)'), - Cards: context.querySelectorAll('.cards:not(.no-autoinit)'), - Carousel: context.querySelectorAll('.carousel:not(.no-autoinit)'), - Chips: context.querySelectorAll('.chips:not(.no-autoinit)'), - Collapsible: context.querySelectorAll('.collapsible:not(.no-autoinit)'), - Datepicker: context.querySelectorAll('.datepicker:not(.no-autoinit)'), - Dropdown: context.querySelectorAll('.dropdown-trigger:not(.no-autoinit)'), - Materialbox: context.querySelectorAll('.materialboxed:not(.no-autoinit)'), - Modal: context.querySelectorAll('.modal:not(.no-autoinit)'), - Parallax: context.querySelectorAll('.parallax:not(.no-autoinit)'), - Pushpin: context.querySelectorAll('.pushpin:not(.no-autoinit)'), - ScrollSpy: context.querySelectorAll('.scrollspy:not(.no-autoinit)'), - FormSelect: context.querySelectorAll('select:not(.no-autoinit)'), - Sidenav: context.querySelectorAll('.sidenav:not(.no-autoinit)'), - Tabs: context.querySelectorAll('.tabs:not(.no-autoinit)'), - TapTarget: context.querySelectorAll('.tap-target:not(.no-autoinit)'), - Timepicker: context.querySelectorAll('.timepicker:not(.no-autoinit)'), - Tooltip: context.querySelectorAll('.tooltipped:not(.no-autoinit)'), - FloatingActionButton: context.querySelectorAll('.fixed-action-btn:not(.no-autoinit)') - }; - Autocomplete.init(registry.Autocomplete, options?.Autocomplete ?? {}); - Cards.init(registry.Cards, options?.Cards ?? {}); - Carousel.init(registry.Carousel, options?.Carousel ?? {}); - Chips.init(registry.Chips, options?.Chips ?? {}); - Collapsible.init(registry.Collapsible, options?.Collapsible ?? {}); - Datepicker.init(registry.Datepicker, options?.Datepicker ?? {}); - Dropdown.init(registry.Dropdown, options?.Dropdown ?? {}); - Materialbox.init(registry.Materialbox, options?.Materialbox ?? {}); - Modal.init(registry.Modal, options?.Modal ?? {}); - Parallax.init(registry.Parallax, options?.Parallax ?? {}); - Pushpin.init(registry.Pushpin, options?.Pushpin ?? {}); - ScrollSpy.init(registry.ScrollSpy, options?.ScrollSpy ?? {}); - FormSelect.init(registry.FormSelect, options?.FormSelect ?? {}); - Sidenav.init(registry.Sidenav, options?.Sidenav ?? {}); - Tabs.init(registry.Tabs, options?.Tabs ?? {}); - TapTarget.init(registry.TapTarget, options?.TapTarget ?? {}); - Timepicker.init(registry.Timepicker, options?.Timepicker ?? {}); - Tooltip.init(registry.Tooltip, options?.Tooltip ?? {}); - FloatingActionButton.init(registry.FloatingActionButton, options?.FloatingActionButton ?? {}); - } - // Init - if (typeof document !== 'undefined') { - document.addEventListener('keydown', Utils.docHandleKeydown, true); - document.addEventListener('keyup', Utils.docHandleKeyup, true); - document.addEventListener('focus', Utils.docHandleFocus, true); - document.addEventListener('blur', Utils.docHandleBlur, true); - } - Forms.Init(); - Chips.Init(); - Waves.Init(); - Range.Init(); - Cards.Init(); - - exports.AutoInit = AutoInit; - exports.Autocomplete = Autocomplete; - exports.Cards = Cards; - exports.Carousel = Carousel; - exports.CharacterCounter = CharacterCounter; - exports.Chips = Chips; - exports.Collapsible = Collapsible; - exports.Datepicker = Datepicker; - exports.Dropdown = Dropdown; - exports.FloatingActionButton = FloatingActionButton; - exports.FormSelect = FormSelect; - exports.Forms = Forms; - exports.Materialbox = Materialbox; - exports.Modal = Modal; - exports.Parallax = Parallax; - exports.Pushpin = Pushpin; - exports.Range = Range; - exports.ScrollSpy = ScrollSpy; - exports.Sidenav = Sidenav; - exports.Slider = Slider; - exports.Tabs = Tabs; - exports.TapTarget = TapTarget; - exports.Timepicker = Timepicker; - exports.Toast = Toast; - exports.Tooltip = Tooltip; - exports.Waves = Waves; - exports.version = version; - - return exports; - -})({}); diff --git a/dist/js/materialize.min.js b/dist/js/materialize.min.js deleted file mode 100644 index aede528a0c..0000000000 --- a/dist/js/materialize.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! -* Materialize v2.3.3 (https://materializeweb.com) -* Copyright 2014-2026 Materialize -* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE) -*/ -var M=function(t){"use strict";class e{static tabPressed=!1;static keyDown=!1;static keys={TAB:["Tab"],ENTER:["Enter"],ESC:["Escape","Esc"],BACKSPACE:["Backspace"],ARROW_UP:["ArrowUp","Up"],ARROW_DOWN:["ArrowDown","Down"],ARROW_LEFT:["ArrowLeft","Left"],ARROW_RIGHT:["ArrowRight","Right"],DELETE:["Delete","Del"]};static docHandleKeydown(t){e.keyDown=!0,[...e.keys.TAB,...e.keys.ARROW_DOWN,...e.keys.ARROW_UP].includes(t.key)&&(e.tabPressed=!0)}static docHandleKeyup(t){e.keyDown=!1,[...e.keys.TAB,...e.keys.ARROW_DOWN,...e.keys.ARROW_UP].includes(t.key)&&(e.tabPressed=!1)}static docHandleFocus(t){e.keyDown&&document.body.classList.add("keyboard-focused")}static docHandleBlur(t){document.body.classList.remove("keyboard-focused")}static guid(){const t=()=>Math.floor(65536*(1+Math.random())).toString(16).substring(1);return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()}static checkWithinContainer(t,e,i){const s={top:!1,right:!1,bottom:!1,left:!1},n=t.getBoundingClientRect(),o=t===document.body?Math.max(n.bottom,window.innerHeight):n.bottom,a=t.scrollLeft,l=t.scrollTop,r=e.left-a,h=e.top-l;return(rn.right-i||r+e.width>window.innerWidth-i)&&(s.right=!0),(ho-i||h+e.height>window.innerHeight-i)&&(s.bottom=!0),s}static checkPossibleAlignments(t,e,i,s){const n={top:!0,right:!0,bottom:!0,left:!0,spaceOnTop:null,spaceOnRight:null,spaceOnBottom:null,spaceOnLeft:null},o="visible"===getComputedStyle(e).overflow,a=e.getBoundingClientRect(),l=Math.min(a.height,window.innerHeight),r=Math.min(a.width,window.innerWidth),h=t.getBoundingClientRect(),d=e.scrollLeft,c=e.scrollTop,p=i.left-d,u=i.top-c,m=i.top+h.height-c;return n.spaceOnRight=o?window.innerWidth-(h.left+i.width):r-(p+i.width),n.spaceOnRight<0&&(n.left=!1),n.spaceOnLeft=o?h.right-i.width:p-i.width+h.width,n.spaceOnLeft<0&&(n.right=!1),n.spaceOnBottom=o?window.innerHeight-(h.top+i.height+s):l-(u+i.height+s),n.spaceOnBottom<0&&(n.top=!1),n.spaceOnTop=o?h.bottom-(i.height+s):m-(i.height-s),n.spaceOnTop<0&&(n.bottom=!1),n}static getIdFromTrigger(t){let e=t.dataset.target;return e||(e=t.getAttribute("href"),e?e.slice(1):"")}static getDocumentScrollTop(){return window.scrollY||document.documentElement.scrollTop||document.body.scrollTop||0}static getDocumentScrollLeft(){return window.scrollX||document.documentElement.scrollLeft||document.body.scrollLeft||0}static throttle(t,e,i={}){let s,n,o,a=null,l=0;const r=()=>{l=!1===i.leading?0:(new Date).getTime(),a=null,o=t.apply(s,n),s=n=null};return(...s)=>{const n=(new Date).getTime();l||!1!==i.leading||(l=n);const h=e-(n-l);return h<=0?(clearTimeout(a),a=null,l=n,o=t.apply(this,s)):a||!1===i.trailing||(a=setTimeout(r,h)),o}}static createConfirmationContainer(t,e,i,s,n){const o=document.createElement("div");o.classList.add("confirmation-btns"),t.append(o),this.createButton(o,i,["btn-cancel"],!0,n),this.createButton(o,e,["btn-confirm"],!0,s)}static createButton(t,i,s=[],n=!0,o=null){s=s.concat(["btn","waves-effect","text"]);const a=document.createElement("button");a.className=s.join(" "),a.style.visibility=n?"visible":"hidden",a.type="button",a.tabIndex=n?0:-1,a.innerText=i,a.addEventListener("click",o),a.addEventListener("keypress",t=>{e.keys.ENTER.includes(t.key)&&o(t)}),t.append(a)}static _setAbsolutePosition(t,i,s,n,o,a="center"){const l=t.offsetHeight,r=t.offsetWidth,h=i.offsetHeight,d=i.offsetWidth;let c=0,p=0,u=t.getBoundingClientRect().top+e.getDocumentScrollTop(),m=t.getBoundingClientRect().left+e.getDocumentScrollLeft();"top"===s?(u+=-h-n,"center"===a&&(m+=r/2-d/2),p=-o):"right"===s?(u+=l/2-h/2,m=r+n,c=o):"left"===s?(u+=l/2-h/2,m=-d-n,c=-o):(u+=l+n,"center"===a&&(m+=r/2-d/2),p=o),"right"===a&&(m+=r-d-n);const v=e._repositionWithinScreen(m,u,d,h,n,o,a);return i.style.top=v.y+"px",i.style.left=v.x+"px",{x:c,y:p}}static _repositionWithinScreen(t,i,s,n,o,a,l){const r=e.getDocumentScrollLeft(),h=e.getDocumentScrollTop();let d=t-r,c=i-h;const p={left:d,top:c,width:s,height:n};let u;"left"===l||"center"==l?u=o+a:"right"===l&&(u=o-a);const m=e.checkWithinContainer(document.body,p,u);return m.left?d=u:m.right&&(d-=d+s-window.innerWidth),m.top?c=u:m.bottom&&(c-=c+n-window.innerHeight),{x:d+r,y:c+h}}}class i{el;options;constructor(t,e,i){t instanceof HTMLElement||console.error(Error(t+" is not an HTML Element"));const s=i.getInstance(t);s&&s.destroy(),this.el=t}static init(t,e,i){let s=null;if(t instanceof Element)s=new i(t,e);else if(t&&t.length){s=[];for(let n=0;n{t.preventDefault(),this.isOpen?this.close():this.open()};_handleMouseEnter=()=>{this.open()};_handleMouseLeave=t=>{const e=t.relatedTarget,i=!!e.closest(".dropdown-content");let s=!1;const n=e.closest(".dropdown-trigger");n&&n.M_Dropdown&&n.M_Dropdown.isOpen&&(s=!0),s||i||this.close()};_handleDocumentClick=t=>{const e=t.target;this.options.closeOnClick&&e.closest(".dropdown-content")&&!this.isTouchMoving?this.close():e.closest(".dropdown-content")||setTimeout(()=>{this.isOpen&&this.close()},0),this.isTouchMoving=!1};_handleTriggerKeydown=t=>{(e.keys.ARROW_DOWN.includes(t.key)||e.keys.ENTER.includes(t.key))&&!this.isOpen&&(t.preventDefault(),this.open())};_handleDocumentTouchmove=t=>{t.target.closest(".dropdown-content")&&(this.isTouchMoving=!0)};_handleDropdownClick=t=>{if("function"==typeof this.options.onItemClick){const e=t.target.closest("li");this.options.onItemClick.call(this,e)}};_handleDropdownKeydown=t=>{const i=e.keys.ARROW_DOWN.includes(t.key)||e.keys.ARROW_UP.includes(t.key);if(e.keys.TAB.includes(t.key))t.preventDefault(),this.close();else if(i&&this.isOpen){t.preventDefault();const i=e.keys.ARROW_DOWN.includes(t.key)?1:-1;let s=this.focusedIndex,n=!1;do{if(s+=i,this.dropdownEl.children[s]&&-1!==this.dropdownEl.children[s].tabIndex){n=!0;break}}while(s=0);n&&(this.focusedIndex>=0&&this.dropdownEl.children[this.focusedIndex].classList.remove("active"),this.focusedIndex=s,this._focusFocusedItem())}else if(e.keys.ENTER.includes(t.key)&&this.isOpen){const t=this.dropdownEl.children[this.focusedIndex],e=t?.querySelector("a, button");e?e.click():t&&t instanceof HTMLElement&&t.click()}else e.keys.ESC.includes(t.key)&&this.isOpen&&(t.preventDefault(),this.close());const s=t.key.toLowerCase(),n=/[a-zA-Z0-9-_]/.test(s),o=[...e.keys.ARROW_DOWN,...e.keys.ARROW_UP,...e.keys.ENTER,...e.keys.ESC,...e.keys.TAB];if(n&&!o.includes(t.key)){this.filterQuery.push(s);const t=this.filterQuery.join(""),e=Array.from(this.dropdownEl.querySelectorAll("li")).find(e=>0===e.innerText.toLowerCase().indexOf(t));e&&(this.focusedIndex=[...e.parentNode.children].indexOf(e),this._focusFocusedItem())}this.filterTimeout=setTimeout(this._resetFilterQuery,1e3)};_handleWindowResize=()=>{this.el.offsetParent&&this.recalculateDimensions()};_resetFilterQuery=()=>{this.filterQuery=[]};_resetDropdownStyles(){this.dropdownEl.style.display="",this._resetDropdownPositioningStyles(),this.dropdownEl.style.transform="",this.dropdownEl.style.opacity=""}_resetDropdownPositioningStyles(){this.dropdownEl.style.width="",this.dropdownEl.style.height="",this.dropdownEl.style.left="",this.dropdownEl.style.top="",this.dropdownEl.style.transformOrigin=""}_moveDropdownToElement(t=null){this.options.container?this.options.container.append(this.dropdownEl):t?t.contains(this.dropdownEl)||t.append(this.dropdownEl):this.el.after(this.dropdownEl)}_makeDropdownFocusable(){this.dropdownEl&&(this.dropdownEl.popover="",this.dropdownEl.tabIndex=0,Array.from(this.dropdownEl.children).forEach(t=>{t.getAttribute("tabindex")||t.setAttribute("tabindex","0")}))}_focusFocusedItem(){this.focusedIndex>=0&&this.focusedIndexh.spaceOnBottom?(d="bottom",n+=h.spaceOnTop,l-=this.options.coverTrigger?h.spaceOnTop-20:h.spaceOnTop-20+i.height):n+=h.spaceOnBottom)),!h[c]){const t="left"===c?"right":"left";h[t]?c=t:h.spaceOnLeft>h.spaceOnRight?(c="right",o+=h.spaceOnLeft,a-=h.spaceOnLeft):(c="left",o+=h.spaceOnRight)}return"bottom"===d&&(l=l-s.height+(this.options.coverTrigger?i.height:0)),"right"===c&&(a=a-s.width+i.width),{x:a,y:l,verticalAlignment:d,horizontalAlignment:c,height:n,width:o}}_animateIn(){const t=this.options.inDuration;this.dropdownEl.style.transition="none",this.dropdownEl.style.opacity="0",this.dropdownEl.style.transform="scale(0.3, 0.3)",setTimeout(()=>{this.dropdownEl.style.transition=`opacity ${t}ms ease, transform ${t}ms ease`,this.dropdownEl.style.opacity="1",this.dropdownEl.style.transform="scale(1, 1)"},1),setTimeout(()=>{this.options.autoFocus&&this.dropdownEl.focus(),"function"==typeof this.options.onOpenEnd&&this.options.onOpenEnd.call(this,this.el)},t)}_animateOut(){const t=this.options.outDuration;this.dropdownEl.style.transition=`opacity ${t}ms ease, transform ${t}ms ease`,this.dropdownEl.style.opacity="0",this.dropdownEl.style.transform="scale(0.3, 0.3)",setTimeout(()=>{this._resetDropdownStyles(),"function"==typeof this.options.onCloseEnd&&this.options.onCloseEnd.call(this,this.el)},t)}_getClosestAncestor(t,e){let i=t.parentNode;for(;null!==i&&i!==document;){if(e(i))return i;i=i.parentElement}return null}_placeDropdown(){let t=this._getClosestAncestor(this.dropdownEl,t=>!["HTML","BODY"].includes(t.tagName)&&"visible"!==getComputedStyle(t).overflow);t||(t=this.dropdownEl.offsetParent?this.dropdownEl.offsetParent:this.dropdownEl.parentNode),"static"===getComputedStyle(t).position&&(t.style.position="relative");const e=this.options.constrainWidth?this.el.getBoundingClientRect().width:this.dropdownEl.getBoundingClientRect().width;this.dropdownEl.style.width=e+"px";const i=this._getDropdownPosition(t);this.dropdownEl.style.left=i.x+"px",this.dropdownEl.style.top=i.y+"px",this.dropdownEl.style.height=i.height+"px",this.dropdownEl.style.width=i.width+"px",this.dropdownEl.style.transformOrigin=`${"left"===i.horizontalAlignment?"0":"100%"} ${"top"===i.verticalAlignment?"0":"100%"}`}open=()=>{this.isOpen||(this.isOpen=!0,"function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,this.el),this._resetDropdownStyles(),this.dropdownEl.style.display="block",this._placeDropdown(),this._animateIn(),setTimeout(()=>this._setupTemporaryEventHandlers(),0),this.el.ariaExpanded="true")};close=()=>{this.isOpen&&(this.isOpen=!1,this.focusedIndex=-1,"function"==typeof this.options.onCloseStart&&this.options.onCloseStart.call(this,this.el),this._animateOut(),this._removeTemporaryEventHandlers(),this.options.autoFocus&&this.el.focus(),this.el.ariaExpanded="false")};recalculateDimensions=()=>{this.isOpen&&(this._resetDropdownPositioningStyles(),this._placeDropdown())}}const o={data:[],onAutocomplete:null,dropdownOptions:{autoFocus:!1,closeOnClick:!1,coverTrigger:!1},minLength:1,isMultiSelect:!1,onSearch:(t,e)=>{const i=t.toLocaleLowerCase();e.setMenuItems(e.data.filter(t=>t.id.toString().toLocaleLowerCase().includes(i)||t.text?.toLocaleLowerCase().includes(i)))},maxDropDownHeight:"300px",allowUnsafeHTML:!1,selected:[]};class a extends i{isOpen;count;activeIndex;oldVal;$active;_mousedown;container;dropdown;static _keydown;selectedValues;menuItems;data;constructor(t,e){super(t,e,a),this.el.M_Autocomplete=this,this.options={...a.defaults,...e},this.isOpen=!1,this.count=0,this.activeIndex=-1,this.oldVal="",this.selectedValues=this.selectedValues||this.options.selected.map(t=>({id:t}))||[],this.menuItems=this.options.data||[],this.data=this.options.data||[],this.$active=null,this._mousedown=!1,this._setupDropdown(),this._setupEventHandlers()}static get defaults(){return o}static init(t,e={}){return super.init(t,e,a)}static getInstance(t){return t.M_Autocomplete}destroy(){this._removeEventHandlers(),this._removeDropdown(),this.el.M_Autocomplete=void 0}_setupEventHandlers(){this.el.addEventListener("blur",this._handleInputBlur),this.el.addEventListener("keyup",this._handleInputKeyup),this.el.addEventListener("focus",this._handleInputFocus),this.el.addEventListener("keydown",this._handleInputKeydown),this.el.addEventListener("click",this._handleInputClick),this.container.addEventListener("mousedown",this._handleContainerMousedownAndTouchstart),this.container.addEventListener("mouseup",this._handleContainerMouseupAndTouchend),void 0!==window.ontouchstart&&(this.container.addEventListener("touchstart",this._handleContainerMousedownAndTouchstart),this.container.addEventListener("touchend",this._handleContainerMouseupAndTouchend))}_removeEventHandlers(){this.el.removeEventListener("blur",this._handleInputBlur),this.el.removeEventListener("keyup",this._handleInputKeyup),this.el.removeEventListener("focus",this._handleInputFocus),this.el.removeEventListener("keydown",this._handleInputKeydown),this.el.removeEventListener("click",this._handleInputClick),this.container.removeEventListener("mousedown",this._handleContainerMousedownAndTouchstart),this.container.removeEventListener("mouseup",this._handleContainerMouseupAndTouchend),void 0!==window.ontouchstart&&(this.container.removeEventListener("touchstart",this._handleContainerMousedownAndTouchstart),this.container.removeEventListener("touchend",this._handleContainerMouseupAndTouchend))}_setupDropdown(){this.container=document.createElement("ul"),this.container.style.maxHeight=this.options.maxDropDownHeight,this.container.id=`autocomplete-options-${e.guid()}`,this.container.classList.add("autocomplete-content","dropdown-content"),this.container.ariaExpanded="true",this.el.setAttribute("data-target",this.container.id),this.menuItems.forEach(t=>{const e=this._createDropdownItem(t);this.container.append(e)}),this.el.parentElement.appendChild(this.container);const t={...a.defaults.dropdownOptions,...this.options.dropdownOptions},i=t.onItemClick;t.onItemClick=t=>{if(!t)return;const e=t.getAttribute("data-id");this.selectOption(e),i&&"function"==typeof i&&i.call(this.dropdown,this.el)},this.dropdown=n.init(this.el,t);const s=this.el.parentElement.querySelector("label");if(s&&this.el.after(s),this.el.removeEventListener("click",this.dropdown._handleClick),!this.options.isMultiSelect&&0!==this.options.selected.length){const t=this.menuItems.filter(t=>t.id===this.selectedValues[0].id);this.el.value=t[0].text}this.el.value&&this.selectOption(this.el.value);const o=document.createElement("div");o.classList.add("status-info"),o.setAttribute("style","position: absolute;right:0;top:0;"),this.el.parentElement.appendChild(o),this._updateSelectedInfo()}_removeDropdown(){this.container.ariaExpanded="false",this.container.parentNode.removeChild(this.container)}_handleInputBlur=()=>{this._mousedown||(this.close(),this._resetAutocomplete())};_handleInputKeyup=t=>{"keyup"===t.type&&(a._keydown=!1),this.count=0;const i=this.el.value.toLocaleLowerCase();e.keys.ENTER.includes(t.key)||e.keys.ARROW_UP.includes(t.key)||e.keys.ARROW_DOWN.includes(t.key)||(this.oldVal!==i&&e.tabPressed&&this.open(),this._inputChangeDetection(i))};_handleInputFocus=()=>{this.count=0;const t=this.el.value.toLocaleLowerCase();this._inputChangeDetection(t)};_inputChangeDetection=t=>{this.oldVal!==t&&(this._setStatusLoading(),this.options.onSearch(this.el.value,this)),this.options.isMultiSelect||0!==this.el.value.length||(this.selectedValues=[],this._triggerChanged()),this.oldVal=t};_handleInputKeydown=t=>{a._keydown=!0;const i=this.container.querySelectorAll("li").length;if(e.keys.ENTER.includes(t.key)&&this.activeIndex>=0){const e=this.container.querySelectorAll("li")[this.activeIndex];return void(e&&(this.selectOption(e.getAttribute("data-id")),t.preventDefault()))}(e.keys.ARROW_UP.includes(t.key)||e.keys.ARROW_DOWN.includes(t.key))&&(t.preventDefault(),e.keys.ARROW_UP.includes(t.key)&&this.activeIndex>0&&this.activeIndex--,e.keys.ARROW_DOWN.includes(t.key)&&this.activeIndex=0&&(this.$active=this.container.querySelectorAll("li")[this.activeIndex],this.$active?.classList.add("active"),this.container.children[this.activeIndex].scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"})))};_handleInputClick=()=>{this.open()};_handleContainerMousedownAndTouchstart=()=>{this._mousedown=!0};_handleContainerMouseupAndTouchend=()=>{this._mousedown=!1};_resetCurrentElementPosition(){this.activeIndex=-1,this.$active?.classList.remove("active")}_resetAutocomplete(){this.container.replaceChildren(),this._resetCurrentElementPosition(),this.oldVal=null,this.isOpen=!1,this._mousedown=!1}_highlightPartialText(t,e){const i=e.toLocaleLowerCase().indexOf(""+t.toLocaleLowerCase()),s=i+t.length-1;return-1==i||-1==s?[e,"",""]:[e.slice(0,i),e.slice(i,s+1),e.slice(s+1)]}_createDropdownItem(t){const e=document.createElement("li");if(e.setAttribute("data-id",t.id),e.setAttribute("style","display:grid; grid-auto-flow: column; user-select: none; align-items: center;"),e.tabIndex=0,this.options.isMultiSelect&&(e.innerHTML=`\n
\n e.id===t.id)?' checked="checked"':""}>\n
`),t.image){const i=document.createElement("img");i.classList.add("circle"),i.src=t.image,e.appendChild(i)}const i=this.el.value.toLocaleLowerCase(),s=this._highlightPartialText(i,(t.text||t.id).toString()),n=document.createElement("div");if(n.setAttribute("style","line-height:1.2;font-weight:500;"),this.options.allowUnsafeHTML)n.innerHTML=s[0]+''+s[1]+""+s[2];else if(n.appendChild(document.createTextNode(s[0])),s[1]){const t=document.createElement("span");t.textContent=s[1],t.classList.add("highlight"),n.appendChild(t),n.appendChild(document.createTextNode(s[2]))}const o=document.createElement("div");if(o.classList.add("item-text"),o.setAttribute("style","padding:5px;overflow:hidden;"),e.appendChild(o),e.querySelector(".item-text").appendChild(n),"string"==typeof t.description||"number"==typeof t.description&&!isNaN(t.description)){const i=document.createElement("small");i.setAttribute("style","line-height:1.3;color:grey;white-space:nowrap;text-overflow:ellipsis;display:block;width:90%;overflow:hidden;"),i.innerText=t.description,e.querySelector(".item-text").appendChild(i)}return e.style.gridTemplateColumns=(()=>this.options.isMultiSelect?t.image?"40px min-content auto":"40px auto":t.image?"min-content auto":"auto")(),e}_renderDropdown(){this._resetAutocomplete(),0===this.menuItems.length&&(this.menuItems=this.selectedValues);for(let t=0;t\n \n \n \n '}_updateSelectedInfo(){const t=this.el.parentElement.querySelector(".status-info");t&&(this.options.isMultiSelect?t.innerHTML=this.selectedValues.length.toString():t.innerHTML="")}_refreshInputText(){if(1===this.selectedValues.length){const t=this.selectedValues[0];this.el.value=t.text||t.id}}_triggerChanged(){this.el.dispatchEvent(new Event("change")),"function"==typeof this.options.onAutocomplete&&this.options.onAutocomplete.call(this,this.selectedValues)}open=()=>{const t=this.el.value.toLocaleLowerCase();this._resetAutocomplete(),t.length>=this.options.minLength&&(this.isOpen=!0,this._renderDropdown()),this.dropdown.isOpen?this.dropdown.recalculateDimensions():setTimeout(()=>{this.dropdown.open()},0)};close=()=>{this.dropdown.close()};setMenuItems(t,e=null,i=!0,s=!1){this.menuItems=t,this.options.data=t,s&&(this.data=t),e&&(this.selectedValues=this.menuItems.filter(t=>!(-1===e.indexOf(t.id)))),this.options.isMultiSelect&&this._renderDropdown(),i&&this.open(),this._updateSelectedInfo(),this._triggerChanged()}setValues(t){this.selectedValues=t,this._updateSelectedInfo(),this.options.isMultiSelect||this._refreshInputText(),this._triggerChanged()}selectOption(t){const e=this.menuItems.find(e=>e.id==t);e&&(this.options.isMultiSelect?(this.selectedValues.filter(t=>t.id===e.id).length>=1?this.selectedValues=this.selectedValues.filter(t=>t.id!==e.id):this.selectedValues.push(e),this._renderDropdown(),this.el.focus()):(this.selectedValues=[e],this._refreshInputText(),this._resetAutocomplete(),this.close()),this._updateSelectedInfo(),this._triggerChanged())}selectOptions(t){const e=this.menuItems.filter(e=>!(-1===t.indexOf(e.id)));e&&(this.selectedValues=e,this._renderDropdown())}}const l={direction:"top",hoverEnabled:!0,toolbarEnabled:!1};class r extends i{#t;#e;#i;#s;isOpen;offsetY;offsetX;btnBottom;btnLeft;btnWidth;constructor(t,e){super(t,e,r),this.el.M_FloatingActionButton=this,this.options={...r.defaults,...e},this.isOpen=!1,this.#t=this.el.querySelector("a"),this.#e=this.el.querySelector("ul"),this.#i=Array.from(this.el.querySelectorAll("ul .btn-floating")),this.#s=this.#i.reverse(),this.offsetY=0,this.offsetX=0,this.el.classList.add(`direction-${this.options.direction}`),this.#t.tabIndex=0,this.#e.ariaExpanded="false","top"===this.options.direction?this.offsetY=40:"right"===this.options.direction?this.offsetX=-40:"bottom"===this.options.direction?this.offsetY=-40:this.offsetX=40,this.#n()}static get defaults(){return l}static init(t,e={}){return super.init(t,e,r)}static getInstance(t){return t.M_FloatingActionButton}destroy(){this.#o(),this.el.M_FloatingActionButton=void 0}#n(){this.options.hoverEnabled&&!this.options.toolbarEnabled?(this.el.addEventListener("mouseenter",this.open),this.el.addEventListener("mouseleave",this.close)):this.el.addEventListener("click",this.#a),this.el.addEventListener("keypress",this.#l)}#o(){this.options.hoverEnabled&&!this.options.toolbarEnabled?(this.el.removeEventListener("mouseenter",this.open),this.el.removeEventListener("mouseleave",this.close)):this.el.removeEventListener("click",this.#a),this.el.removeEventListener("keypress",this.#l)}#a=()=>{this.#r()};#l=t=>{e.keys.ENTER.includes(t.key)&&this.#r()};#r=()=>{this.isOpen?this.close():this.open()};#h=t=>{t.target!==this.#e&&this.close()};open=()=>{this.isOpen||(this.options.toolbarEnabled?this.#d():this.#c(),this.isOpen=!0)};close=()=>{this.isOpen&&(this.options.toolbarEnabled?(window.removeEventListener("scroll",this.close,!0),document.body.removeEventListener("click",this.#h,!0)):this.#p(),this.isOpen=!1)};#c(){this.el.classList.add("active"),this.#e.ariaExpanded="true";this.#s.forEach((t,e)=>{const i=40*e;t.style.transition="none",t.style.opacity="0",t.style.transform=`translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`,setTimeout(()=>{t.style.opacity="0.4",setTimeout(()=>{t.style.transition="opacity 275ms ease, transform 275ms ease",t.style.opacity="1",t.style.transform="translate(0, 0) scale(1)",t.tabIndex=0},1)},i)})}#p(){setTimeout(()=>{this.el.classList.remove("active"),this.#e.ariaExpanded="false"},175),this.#s.forEach(t=>{t.style.transition="opacity 175ms ease, transform 175ms ease",t.style.opacity="0",t.style.transform=`translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`,t.tabIndex=-1})}#d(){const t=window.innerWidth,e=window.innerHeight,i=this.el.getBoundingClientRect(),s=document.createElement("div"),n=t/s[0].clientWidth,o=getComputedStyle(this.#t).backgroundColor;s.classList.add("fab-backdrop"),s.style.backgroundColor=o,this.#t.append(s),this.offsetX=i.left-t/2+i.width/2,this.offsetY=e-i.bottom,this.btnBottom=i.bottom,this.btnLeft=i.left,this.btnWidth=i.width,this.el.classList.add("active"),this.el.style.textAlign="center",this.el.style.width="100%",this.el.style.bottom="0",this.el.style.left="0",this.el.style.transform="translateX("+this.offsetX+"px)",this.el.style.transition="none",this.#e.ariaExpanded="true",this.#t.style.transform=`translateY(${this.offsetY}px`,this.#t.style.transition="none",setTimeout(()=>{this.el.style.transform="",this.el.style.transition="transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s",this.#t.style.overflow="visible",this.#t.style.transform="",this.#t.style.transition="transform .2s",setTimeout(()=>{this.el.style.overflow="hidden",this.el.style.backgroundColor=o,s.style.transform="scale("+n+")",s.style.transition="transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)",this.#e.querySelectorAll("li > a").forEach(t=>{t.style.opacity="1",t.tabIndex=0}),window.addEventListener("scroll",this.close,!0),document.body.addEventListener("click",this.#h,!0)},100)},0)}}const h={onOpen:null,onClose:null,inDuration:225,outDuration:300};class d extends i{#u;#m;#v;#g;isOpen=!1;constructor(t,e){super(t,e,d),this.el.M_Cards=this,this.options={...d.defaults,...e},this.#v=[],this.#u=this.el.querySelector(".card-reveal"),this.#u&&(this.#m=getComputedStyle(this.el).overflow,this.#v=Array.from(this.el.querySelectorAll(".activator")),this.#v.forEach(t=>{t&&(t.tabIndex=0)}),this.#g=this.#u?.querySelector(".card-title"),this.#g&&(this.#g.tabIndex=-1),this.#u.ariaExpanded="false",this.#n())}static get defaults(){return h}static init(t,e){return super.init(t,e,d)}static getInstance(t){return t.M_Cards}destroy(){this.#o(),this.#v=[]}#n=()=>{this.#v.forEach(t=>{t.addEventListener("click",this.#_),t.addEventListener("keypress",this.#y)})};#o=()=>{this.#v.forEach(t=>{t.removeEventListener("click",this.#_),t.removeEventListener("keypress",this.#y)})};#_=()=>{this.#f()};#y=t=>{e.keys.ENTER.includes(t.key)&&this.#f()};#f=()=>{this.#v.forEach(t=>t.tabIndex=-1),this.open()};#E=()=>{this.#g.addEventListener("click",this.close),this.#g.addEventListener("keypress",this.#w)};#b=()=>{this.#g.addEventListener("click",this.close),this.#g.addEventListener("keypress",this.#w)};#w=t=>{e.keys.ENTER.includes(t.key)&&this.close()};open=()=>{this.isOpen||(this.isOpen=!0,this.el.style.overflow="hidden",this.#u.style.display="block",this.#u.ariaExpanded="true",this.#g.tabIndex=0,setTimeout(()=>{this.#u.style.transition=`transform ${this.options.outDuration}ms ease`,this.#u.style.transform="translateY(-100%)"},1),"function"==typeof this.options.onOpen&&this.options.onOpen.call(this),this.#E())};close=()=>{this.isOpen&&(this.isOpen=!1,this.#u.style.transition=`transform ${this.options.inDuration}ms ease`,this.#u.style.transform="translateY(0)",setTimeout(()=>{this.#u.style.display="none",this.#u.ariaExpanded="false",this.#v.forEach(t=>t.tabIndex=0),this.#g.tabIndex=-1,this.el.style.overflow=this.#m},this.options.inDuration),"function"==typeof this.options.onClose&&this.options.onClose.call(this),this.#b())};static Init(){"undefined"!=typeof document&&document.addEventListener("DOMContentLoaded",()=>{document.querySelectorAll(".card").forEach(t=>{t&&null==t.M_Card&&this.init(t)})})}}const c={duration:200,dist:-100,shift:0,padding:0,numVisible:5,fullWidth:!1,indicators:!1,noWrap:!1,onCycleTo:null};class p extends i{hasMultipleSlides;showIndicators;noWrap;pressed;dragged;offset;target;images;itemWidth;itemHeight;dim;_indicators;count;xform;verticalDragged;reference;referenceY;velocity;frame;timestamp;ticker;amplitude;center=0;imageHeight;scrollingTimeout;oneTimeCallback;constructor(t,e){super(t,e,p),this.el.M_Carousel=this,this.options={...p.defaults,...e},this.hasMultipleSlides=this.el.querySelectorAll(".carousel-item").length>1,this.showIndicators=this.options.indicators&&this.hasMultipleSlides,this.noWrap=this.options.noWrap||!this.hasMultipleSlides,this.pressed=!1,this.dragged=!1,this.offset=this.target=0,this.images=[],this.itemWidth=this.el.querySelector(".carousel-item").clientWidth,this.itemHeight=this.el.querySelector(".carousel-item").clientHeight,this.dim=2*this.itemWidth+this.options.padding||1,this.options.fullWidth&&(this.options.dist=0,this._setCarouselHeight(),this.showIndicators&&this.el.querySelector(".carousel-fixed-item")?.classList.add("with-indicators")),this._indicators=document.createElement("ul"),this._indicators.classList.add("indicators"),this.el.querySelectorAll(".carousel-item").forEach((t,e)=>{if(this.images.push(t),this.showIndicators){const t=document.createElement("li");t.classList.add("indicator-item"),t.tabIndex=0,0===e&&t.classList.add("active"),this._indicators.appendChild(t)}}),this.showIndicators&&this.el.appendChild(this._indicators),this.count=this.images.length,this.options.numVisible=Math.min(this.count,this.options.numVisible),this.xform="transform",["webkit","Moz","O","ms"].every(t=>{const e=t+"Transform";return void 0===document.body.style[e]||(this.xform=e,!1)}),this._setupEventHandlers(),this._scroll(this.offset)}static get defaults(){return c}static init(t,e={}){return super.init(t,e,p)}static getInstance(t){return t.M_Carousel}destroy(){this._removeEventHandlers(),this.el.M_Carousel=void 0}_setupEventHandlers(){void 0!==window.ontouchstart&&(this.el.addEventListener("touchstart",this._handleCarouselTap),this.el.addEventListener("touchmove",this._handleCarouselDrag),this.el.addEventListener("touchend",this._handleCarouselRelease)),this.el.addEventListener("mousedown",this._handleCarouselTap),this.el.addEventListener("mousemove",this._handleCarouselDrag),this.el.addEventListener("mouseup",this._handleCarouselRelease),this.el.addEventListener("mouseleave",this._handleCarouselRelease),this.el.addEventListener("click",this._handleCarouselClick),this.showIndicators&&this._indicators&&this._indicators.querySelectorAll(".indicator-item").forEach(t=>{t.addEventListener("click",this._handleIndicatorClick),t.addEventListener("keypress",this._handleIndicatorKeyPress)}),window.addEventListener("resize",this._handleThrottledResize)}_removeEventHandlers(){void 0!==window.ontouchstart&&(this.el.removeEventListener("touchstart",this._handleCarouselTap),this.el.removeEventListener("touchmove",this._handleCarouselDrag),this.el.removeEventListener("touchend",this._handleCarouselRelease)),this.el.removeEventListener("mousedown",this._handleCarouselTap),this.el.removeEventListener("mousemove",this._handleCarouselDrag),this.el.removeEventListener("mouseup",this._handleCarouselRelease),this.el.removeEventListener("mouseleave",this._handleCarouselRelease),this.el.removeEventListener("click",this._handleCarouselClick),this.showIndicators&&this._indicators&&this._indicators.querySelectorAll(".indicator-item").forEach(t=>{t.removeEventListener("click",this._handleIndicatorClick)}),window.removeEventListener("resize",this._handleThrottledResize)}_handleThrottledResize=()=>e.throttle(this._handleResize,200,null).bind(this);_handleCarouselTap=t=>{"mousedown"===t.type&&"IMG"===t.target.tagName&&t.preventDefault(),this.pressed=!0,this.dragged=!1,this.verticalDragged=!1,this.reference=this._xpos(t),this.referenceY=this._ypos(t),this.velocity=this.amplitude=0,this.frame=this.offset,this.timestamp=Date.now(),clearInterval(this.ticker),this.ticker=setInterval(this._track,100)};_handleCarouselDrag=t=>{let e,i,s,n;if(this.pressed)if(e=this._xpos(t),i=this._ypos(t),s=this.reference-e,n=Math.abs(this.referenceY-i),n<30&&!this.verticalDragged)(s>2||s<-2)&&(this.dragged=!0,this.reference=e,this._scroll(this.offset+s));else{if(this.dragged)return t.preventDefault(),t.stopPropagation(),!1;this.verticalDragged=!0}if(this.dragged)return t.preventDefault(),t.stopPropagation(),!1};_handleCarouselRelease=t=>{if(this.pressed)return this.pressed=!1,clearInterval(this.ticker),this.target=this.offset,(this.velocity>10||this.velocity<-10)&&(this.amplitude=.9*this.velocity,this.target=this.offset+this.amplitude),this.target=Math.round(this.target/this.dim)*this.dim,this.noWrap&&(this.target>=this.dim*(this.count-1)?this.target=this.dim*(this.count-1):this.target<0&&(this.target=0)),this.amplitude=this.target-this.offset,this.timestamp=Date.now(),requestAnimationFrame(this._autoScroll),this.dragged&&(t.preventDefault(),t.stopPropagation()),!1};_handleCarouselClick=t=>{if(this.dragged)return t.preventDefault(),t.stopPropagation(),!1;if(!this.options.fullWidth){const e=t.target.closest(".carousel-item");if(!e)return;const i=[...e.parentNode.children].indexOf(e);0!==this._wrap(this.center)-i&&(t.preventDefault(),t.stopPropagation()),i<0?t.clientX-t.target.getBoundingClientRect().left>this.el.clientWidth/2?this.next():this.prev():this._cycleTo(i)}};_handleIndicatorClick=t=>{t.stopPropagation(),this._handleIndicatorInteraction(t)};_handleIndicatorKeyPress=t=>{t.stopPropagation(),e.keys.ENTER.includes(t.key)&&this._handleIndicatorInteraction(t)};_handleIndicatorInteraction=t=>{const e=t.target.closest(".indicator-item");if(e){const t=[...e.parentNode.children].indexOf(e);this._cycleTo(t)}};_handleResize=()=>{this.options.fullWidth?(this.itemWidth=this.el.querySelector(".carousel-item").clientWidth,this.imageHeight=this.el.querySelector(".carousel-item.active").clientHeight,this.dim=2*this.itemWidth+this.options.padding,this.offset=2*this.center*this.itemWidth,this.target=this.offset,this._setCarouselHeight(!0)):this._scroll()};_setCarouselHeight(t=!1){const e=this.el.querySelector(".carousel-item.active")?this.el.querySelector(".carousel-item.active"):this.el.querySelector(".carousel-item"),i=e.querySelector("img");if(i)if(i.complete){const t=i.clientHeight;if(t>0)this.el.style.height=t+"px";else{const t=i.naturalWidth,e=i.naturalHeight,s=this.el.clientWidth/t*e;this.el.style.height=s+"px"}}else i.addEventListener("load",()=>{this.el.style.height=i.offsetHeight+"px"});else if(!t){const t=e.clientHeight;this.el.style.height=t+"px"}}_xpos(t){return t.type.startsWith("touch")&&t.targetTouches.length>=1?t.targetTouches[0].clientX:t.clientX}_ypos(t){return t.type.startsWith("touch")&&t.targetTouches.length>=1?t.targetTouches[0].clientY:t.clientY}_wrap(t){return t>=this.count?t%this.count:t<0?this._wrap(this.count+t%this.count):t}_track=()=>{const t=Date.now(),e=t-this.timestamp,i=1e3*(this.offset-this.frame)/(1+e);this.timestamp=t,this.frame=this.offset,this.velocity=.8*i+.2*this.velocity};_autoScroll=()=>{let t,e;this.amplitude&&(t=Date.now()-this.timestamp,e=this.amplitude*Math.exp(-t/this.options.duration),e>2||e<-2?(this._scroll(this.target-e),requestAnimationFrame(this._autoScroll)):this._scroll(this.target))};_scroll(t=0){this.el.classList.contains("scrolling")||this.el.classList.add("scrolling"),null!=this.scrollingTimeout&&clearTimeout(this.scrollingTimeout),this.scrollingTimeout=setTimeout(()=>{this.el.classList.remove("scrolling")},this.options.duration);const e=this.center;this.offset="number"==typeof t?t:this.offset,this.center=Math.floor((this.offset+this.dim/2)/this.dim);const i=this.count>>1,s=this.offset-this.center*this.dim,n=s<0?1:-1,o=-n*s*2/this.dim;let a,l,r,h,d,c;const p=1/this.options.numVisible;if(this.options.fullWidth?(r="translateX(0)",c=1):(r="translateX("+(this.el.clientWidth-this.itemWidth)/2+"px) ",r+="translateY("+(this.el.clientHeight-this.itemHeight)/2+"px)",c=1-p*o),this.showIndicators){const t=this.center%this.count,e=this._indicators.querySelector(".indicator-item.active");if([...e.parentNode.children].indexOf(e)!==t){e.classList.remove("active");const i=t<0?this.count+t:t;this._indicators.querySelectorAll(".indicator-item")[i].classList.add("active")}}if(!this.noWrap||this.center>=0&&this.center0?1-o:1):(h=this.options.dist*(2*a-o*n),d=1-p*(2*a-o*n)),!this.noWrap||this.center-a>=0){l=this.images[this._wrap(this.center-a)];const t=`${r} translateX(${-this.options.shift+(-this.dim*a-s)/2}px) translateZ(${h}px)`;this._updateItemStyle(l,d,-a,t)}}if(!this.noWrap||this.center>=0&&this.center0&&Math.abs(i-this.count)0&&(this.target-=this.dim*i),"function"==typeof e&&(this.oneTimeCallback=e),this.offset!==this.target&&(this.amplitude=this.target-this.offset,this.timestamp=Date.now(),requestAnimationFrame(this._autoScroll))}next(t=1){(void 0===t||isNaN(t))&&(t=1);let e=this.center+t;if(e>=this.count||e<0){if(this.noWrap)return;e=this._wrap(e)}this._cycleTo(e)}prev(t=1){(void 0===t||isNaN(t))&&(t=1);let e=this.center-t;if(e>=this.count||e<0){if(this.noWrap)return;e=this._wrap(e)}this._cycleTo(e)}set(t,e){if((void 0===t||isNaN(t))&&(t=0),t>this.count||t<0){if(this.noWrap)return;t=this._wrap(t)}this._cycleTo(t,e)}}var u;const m={data:[],placeholder:"",secondaryPlaceholder:"",closeIconClass:"material-icons",autocompleteOptions:{},autocompleteOnly:!1,limit:1/0,allowUserInput:!1,onChipAdd:null,onChipSelect:null,onChipDelete:null};function v(t){return[...t.parentNode.children].indexOf(t)}class g extends i{chipsData;hasAutocomplete;autocomplete;#L;#C;#k;static#T;#D;constructor(t,e){super(t,e,u),this.el.M_Chips=this,this.options={...u.defaults,...e},this.el.classList.add("chips"),this.chipsData=[],this.#k=[],this.options.data.length&&(this.chipsData=this.options.data,this.#x()),this.options.allowUserInput&&(this.#S(),this.el.classList.add("input-field"),this.#I(),this.#n(),this.el.append(this.#L))}static get defaults(){return m}static init(t,e={}){return super.init(t,e,u)}static getInstance(t){return t.M_Chips}getData(){return this.chipsData}destroy(){this.options.allowUserInput&&this.#o(),this.#k.forEach(t=>t.remove()),this.#k=[],this.el.M_Chips=void 0}#n(){this.el.addEventListener("click",this.#A),document.addEventListener("keydown",u.#M),document.addEventListener("keyup",u.#O),this.el.addEventListener("blur",u.#R,!0),this.#L.addEventListener("focus",this.#H),this.#L.addEventListener("blur",this.#P),this.#L.addEventListener("keydown",this.#W)}#o(){this.el.removeEventListener("click",this.#A),document.removeEventListener("keydown",u.#M),document.removeEventListener("keyup",u.#O),this.el.removeEventListener("blur",u.#R,!0),this.#L.removeEventListener("focus",this.#H),this.#L.removeEventListener("blur",this.#P),this.#L.removeEventListener("keydown",this.#W)}#A=t=>{const e=t.target.closest(".chip"),i=t.target.classList.contains("close");if(e){const t=[...e.parentNode.children].indexOf(e);i?(this.deleteChip(t),this.#L.focus()):this.selectChip(t)}else this.#L.focus()};static#M(t){u.#T=!0;const i=t.target.closest(".chips"),s=t.target&&i,n=t.target.tagName;if("INPUT"===n||"TEXTAREA"===n||!s)return;const o=i.M_Chips;if(e.keys.BACKSPACE.includes(t.key)||e.keys.DELETE.includes(t.key)){t.preventDefault();let e=o.chipsData.length;if(o.#D){const t=v(o.#D);o.deleteChip(t),o.#D=null,e=Math.max(t-1,0)}o.chipsData.length?o.selectChip(e):o.#L.focus()}else if(e.keys.ARROW_LEFT.includes(t.key)){if(o.#D){const t=v(o.#D)-1;if(t<0)return;o.selectChip(t)}}else if(e.keys.ARROW_RIGHT.includes(t.key)&&o.#D){const t=v(o.#D)+1;t>=o.chipsData.length?o.#L.focus():o.selectChip(t)}}static#O(){u.#T=!1}static#R(t){if(!u.#T&&document.hidden){t.target.closest(".chips").M_Chips.#D=null}}#H=()=>{this.el.classList.add("focus")};#P=()=>{this.el.classList.remove("focus")};#W=t=>{if(u.#T=!0,e.keys.ENTER.includes(t.key)){if(this.hasAutocomplete&&this.autocomplete&&this.autocomplete.isOpen)return;t.preventDefault(),(!this.hasAutocomplete||this.hasAutocomplete&&!this.options.autocompleteOnly)&&this.addChip({id:this.#L.value}),this.#L.value=""}else(e.keys.BACKSPACE.includes(t.key)||e.keys.ARROW_LEFT.includes(t.key))&&""===this.#L.value&&this.chipsData.length&&(t.preventDefault(),this.selectChip(this.chipsData.length-1))};#B(t){if(!t.id)return;const e=document.createElement("li");if(e.classList.add("chip"),e.innerText=t.text||t.id,t.image){const i=document.createElement("img");i.setAttribute("src",t.image),e.insertBefore(i,e.firstChild)}if(this.options.allowUserInput){const t=document.createElement("button");t.classList.add(this.options.closeIconClass,"close"),t.innerText="close",e.appendChild(t)}return e}#x(){this.#k=[];for(let t=0;t{t.length>0&&this.addChip({id:t[0].id,text:t[0].text,image:t[0].image}),this.#L.value="",this.#L.focus()},this.autocomplete=a.init(this.#L,this.options.autocompleteOptions)}#I(){this.#L=this.el.querySelector("input"),this.#L||(this.#L=document.createElement("input"),this.el.append(this.#L)),this.#L.classList.add("input"),this.hasAutocomplete=Object.keys(this.options.autocompleteOptions).length>0,this.hasAutocomplete&&this.#q(),this.#F(),this.#L.getAttribute("id")||this.#L.setAttribute("id",e.guid())}#S(){this.#C=this.el.querySelector("label"),this.#C&&this.#C.setAttribute("for",this.#L.getAttribute("id"))}#F(){void 0!==this.chipsData&&!this.chipsData.length&&this.options.placeholder?this.#L.placeholder=this.options.placeholder:(void 0===this.chipsData||this.chipsData.length)&&this.options.secondaryPlaceholder&&(this.#L.placeholder=this.options.secondaryPlaceholder)}#V(t){const e=!!t.id,i=!this.chipsData.some(e=>e.id==t.id);return e&&i}addChip(t){if(!this.#V(t)||this.chipsData.length>=this.options.limit)return;const e=this.#B(t);this.#k.push(e),this.chipsData.push(t),this.#L.before(e),this.#F(),"function"==typeof this.options.onChipAdd&&this.options.onChipAdd(this.el,e)}deleteChip(t){const e=this.#k[t];this.#k[t].remove(),this.#k.splice(t,1),this.chipsData.splice(t,1),this.#F(),"function"==typeof this.options.onChipDelete&&this.options.onChipDelete(this.el,e)}selectChip(t){const e=this.#k[t];this.#D=e,e.focus(),"function"==typeof this.options.onChipSelect&&this.options.onChipSelect(this.el,e)}static Init(){"undefined"!=typeof document&&document.addEventListener("DOMContentLoaded",()=>{document.querySelectorAll(".chips").forEach(t=>{t.addEventListener("click",t=>{if(t.target.classList.contains("close")){const e=t.target.closest(".chip");e&&e.remove()}})})})}static{this.#T=!1}}u=g;const _={accordion:!0,onOpenStart:null,onOpenEnd:null,onCloseStart:null,onCloseEnd:null,inDuration:300,outDuration:300};class y extends i{_headers;constructor(t,e){super(t,e,y),this.el.M_Collapsible=this,this.options={...y.defaults,...e},this._headers=Array.from(this.el.querySelectorAll("li > .collapsible-header")),this._headers.forEach(t=>t.tabIndex=0),this._setupEventHandlers();const i=Array.from(this.el.querySelectorAll("li.active > .collapsible-body"));this.options.accordion?i.length>0&&this._setExpanded(i[0]):i.forEach(t=>this._setExpanded(t))}static get defaults(){return _}static init(t,e={}){return super.init(t,e,y)}static getInstance(t){return t.M_Collapsible}destroy(){this._removeEventHandlers(),this.el.M_Collapsible=void 0}_setupEventHandlers(){this.el.addEventListener("click",this._handleCollapsibleClick),this._headers.forEach(t=>t.addEventListener("keydown",this._handleCollapsibleKeydown))}_removeEventHandlers(){this.el.removeEventListener("click",this._handleCollapsibleClick),this._headers.forEach(t=>t.removeEventListener("keydown",this._handleCollapsibleKeydown))}_handleCollapsibleClick=t=>{const e=t.target.closest(".collapsible-header");if(t.target&&e){if(e.closest(".collapsible")!==this.el)return;const t=e.closest("li"),i=t.classList.contains("active"),s=[...t.parentNode.children].indexOf(t);i?this.close(s):this.open(s)}};_handleCollapsibleKeydown=t=>{e.keys.ENTER.includes(t.key)&&this._handleCollapsibleClick(t)};_setExpanded(t){t.style.maxHeight=t.scrollHeight+"px"}_animateIn(t){const e=this.el.children[t];if(!e)return;const i=e.querySelector(".collapsible-body"),s=this.options.inDuration;i.style.transition=`max-height ${s}ms ease-out`,this._setExpanded(i),setTimeout(()=>{"function"==typeof this.options.onOpenEnd&&this.options.onOpenEnd.call(this,e)},s)}_animateOut(t){const e=this.el.children[t];if(!e)return;const i=e.querySelector(".collapsible-body"),s=this.options.outDuration;i.style.transition=`max-height ${s}ms ease-out`,i.style.maxHeight="0",setTimeout(()=>{"function"==typeof this.options.onCloseEnd&&this.options.onCloseEnd.call(this,e)},s)}open=t=>{const e=Array.from(this.el.children).filter(t=>"LI"===t.tagName),i=e[t];if(i&&!i.classList.contains("active")){if("function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,i),this.options.accordion){const t=e.filter(t=>t.classList.contains("active"));t.forEach(t=>{const i=e.indexOf(t);this.close(i)})}i.classList.add("active"),this._animateIn(t)}};close=t=>{const e=Array.from(this.el.children).filter(t=>"LI"===t.tagName)[t];e&&e.classList.contains("active")&&("function"==typeof this.options.onCloseStart&&this.options.onCloseStart.call(this,e),e.classList.remove("active"),this._animateOut(t))}}const f={classes:"",dropdownOptions:{}};class E extends i{isMultiple;labelEl;dropdownOptions;input;dropdown;wrapper;selectOptions;_values;nativeTabIndex;constructor(t,e){super(t,e,E),this.el.classList.contains("browser-default")||(this.el.M_FormSelect=this,this.options={...E.defaults,...e},this.isMultiple=this.el.multiple,this.nativeTabIndex=this.el.tabIndex??-1,this.el.tabIndex=-1,this._values=[],this._setupDropdown(),this._setupEventHandlers())}static get defaults(){return f}static init(t,e={}){return super.init(t,e,E)}static getInstance(t){return t.M_FormSelect}destroy(){this._removeEventHandlers(),this._removeDropdown(),this.el.M_FormSelect=void 0}_setupEventHandlers(){this.dropdownOptions.querySelectorAll("li:not(.optgroup)").forEach(t=>{t.addEventListener("click",this._handleOptionClick),t.addEventListener("keydown",t=>{" "!==t.key&&"Enter"!==t.key||this._handleOptionClick(t)})}),this.el.addEventListener("change",this._handleSelectChange),this.input.addEventListener("click",this._handleInputClick)}_removeEventHandlers(){this.dropdownOptions.querySelectorAll("li:not(.optgroup)").forEach(t=>{t.removeEventListener("click",this._handleOptionClick)}),this.el.removeEventListener("change",this._handleSelectChange),this.input.removeEventListener("click",this._handleInputClick)}_handleSelectChange=()=>{this._setValueToInput()};_handleOptionClick=t=>{t.preventDefault();const e=t.target.closest("li");this._selectOptionElement(e),t.stopPropagation()};_arraysEqual(t,e){if(t===e)return!0;if(null==t||null==e)return!1;if(t.length!==e.length)return!1;for(let i=0;ie.optionEl===t),i=this.getSelectedValues();this.isMultiple?this._toggleEntryFromArray(e):(this._deselectAll(),this._selectValue(e)),this._setValueToInput();const s=this.getSelectedValues();!this._arraysEqual(i,s)&&this.el.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0,composed:!0}))}this.isMultiple||this.dropdown.close()}_handleInputClick=()=>{this.dropdown&&this.dropdown.isOpen&&(this._setValueToInput(),this._setSelectedStates())};_setupDropdown(){this.labelEl=document.querySelector('[for="'+this.el.id+'"]'),this.wrapper=document.createElement("div"),this.wrapper.classList.add("select-wrapper","input-field"),this.options.classes.length>0&&this.wrapper.classList.add(...this.options.classes.split(" ")),this.el.before(this.wrapper);const t=document.createElement("div");t.classList.add("hide-select"),this.wrapper.append(t),t.appendChild(this.el),this.el.disabled&&this.wrapper.classList.add("disabled"),this.selectOptions=Array.from(this.el.children).filter(t=>["OPTION","OPTGROUP"].includes(t.tagName)),this.dropdownOptions=document.createElement("ul"),this.dropdownOptions.id=`select-options-${e.guid()}`,this.dropdownOptions.setAttribute("popover","auto"),this.dropdownOptions.classList.add("dropdown-content","select-dropdown"),this.dropdownOptions.setAttribute("role","listbox"),this.dropdownOptions.ariaMultiSelectable=this.isMultiple.toString(),this.isMultiple&&this.dropdownOptions.classList.add("multiple-select-dropdown"),this.selectOptions.length>0&&this.selectOptions.forEach(t=>{if("OPTION"===t.tagName){const e=this._createAndAppendOptionWithIcon(t,this.isMultiple?"multiple":void 0);this._addOptionToValues(t,e)}else if("OPTGROUP"===t.tagName){const i="opt-group-"+e.guid(),s=document.createElement("li");s.classList.add("optgroup"),s.tabIndex=-1,s.setAttribute("role","group"),s.setAttribute("aria-labelledby",i),s.innerHTML=`${t.getAttribute("label")}`,this.dropdownOptions.append(s);const n=[];Array.from(t.children).filter(t=>"OPTION"===t.tagName).forEach(t=>{const i=this._createAndAppendOptionWithIcon(t,"optgroup-option"),s="opt-child-"+e.guid();i.id=s,n.push(s),this._addOptionToValues(t,i)}),s.setAttribute("aria-owns",n.join(" "))}}),this.wrapper.append(this.dropdownOptions),this.input=document.createElement("input"),this.input.id="m_select-input-"+e.guid(),this.input.classList.add("select-dropdown","dropdown-trigger"),this.input.type="text",this.input.readOnly=!0,this.input.setAttribute("data-target",this.dropdownOptions.id),this.input.ariaReadOnly="true",this.input.ariaRequired=this.el.hasAttribute("required").toString(),this.el.disabled&&(this.input.disabled=!0),this.input.setAttribute("tabindex",this.nativeTabIndex.toString());const i=this.el.attributes;for(let t=0;t{const t=this.dropdownOptions.querySelector(".selected");if(t&&(e.keyDown=!0,this.dropdown.focusedIndex=[...t.parentNode.children].indexOf(t),this.dropdown._focusFocusedItem(),e.keyDown=!1,this.dropdown.isScrollable)){let e=t.getBoundingClientRect().top-this.dropdownOptions.getBoundingClientRect().top;e-=this.dropdownOptions.clientHeight/2,this.dropdownOptions.scrollTop=e}this.input.ariaExpanded="true",i&&"function"==typeof i&&i.call(this.dropdown,this.el)},t.onCloseEnd=()=>{this.input.ariaExpanded="false",s&&"function"==typeof s&&s.call(this.dropdown,this.el)},t.closeOnClick=!1,this.dropdown=n.init(this.input,t)}this._setSelectedStates(),this.labelEl&&this.input.after(this.labelEl)}_addOptionToValues(t,e){this._values.push({el:t,optionEl:e})}_removeDropdown(){this.wrapper.querySelector(".caret").remove(),this.input.remove(),this.dropdownOptions.remove(),this.wrapper.before(this.el),this.wrapper.remove()}_createAndAppendOptionWithIcon(t,e){const i=document.createElement("li");i.setAttribute("role","option"),t.disabled&&(i.classList.add("disabled"),i.ariaDisabled="true"),"optgroup-option"===e&&i.classList.add(e);const s=document.createElement("span");s.innerHTML=t.innerHTML,this.isMultiple&&!t.disabled&&(s.innerHTML=``),i.appendChild(s);const n=t.getAttribute("data-icon"),o=t.getAttribute("class")?.split(" ");if(n){const t=document.createElement("img");o&&t.classList.add(...o),t.src=n,t.ariaHidden="true",i.prepend(t)}return this.dropdownOptions.append(i),i}_selectValue(t){t.el.selected=!0,t.optionEl.classList.add("selected"),t.optionEl.ariaSelected="true";const e=t.optionEl.querySelector('input[type="checkbox"]');e&&(e.checked=!0)}_deselectValue(t){t.el.selected=!1,t.optionEl.classList.remove("selected"),t.optionEl.ariaSelected="false";const e=t.optionEl.querySelector('input[type="checkbox"]');e&&(e.checked=!1)}_deselectAll(){this._values.forEach(t=>this._deselectValue(t))}_isValueSelected(t){return this.getSelectedValues().some(e=>e===t.el.value)}_toggleEntryFromArray(t){this._isValueSelected(t)?this._deselectValue(t):this._selectValue(t)}_getSelectedOptions(){return Array.prototype.filter.call(this.el.selectedOptions,t=>t)}_setValueToInput(){const t=this._getSelectedOptions(),e=this._values.filter(e=>t.indexOf(e.el)>=0).filter(t=>!t.el.disabled).map(t=>t.optionEl.querySelector("span").innerText.trim());if(0===e.length){const t=this.el.querySelector("option:disabled");if(t&&""===t.value)return void(this.input.value=t.innerText)}this.input.value=e.join(", ")}_setSelectedStates(){this._values.forEach(t=>{const e=t.el.selected,i=t.optionEl.querySelector('input[type="checkbox"]');i&&(i.checked=e),e?this._activateOption(this.dropdownOptions,t.optionEl):(t.optionEl.classList.remove("selected"),t.optionEl.ariaSelected="false")})}_activateOption(t,e){e&&(this.isMultiple||t.querySelectorAll("li.selected").forEach(t=>t.classList.remove("selected")),e.classList.add("selected"),e.ariaSelected="true")}getSelectedValues(){return this._getSelectedOptions().map(t=>t.value)}}const w={margin:5,transition:10,duration:250,align:"left",title:null,onOpen:null,onClose:null};class b{el;container;options;visible;constructor(t,e,i){this.el=t,this.options={...w,...i},this.container=document.createElement("div"),this.container.classList.add("display-docked"),this.container.append(e),t.parentElement.append(this.container),document.addEventListener("click",t=>{this.visible&&this.el!==t.target&&!t.target.closest(".display-docked")&&this.hide()},!0)}static init(t,e,i){return new b(t,e,i)}show=()=>{if(this.visible)return;this.visible=!0;const t=e._setAbsolutePosition(this.el,this.container,"bottom",this.options.margin,this.options.transition,this.options.align);this.container.style.visibility="visible",this.container.style.transition=`\n transform ${this.options.duration}ms ease-out,\n opacity ${this.options.duration}ms ease-out`,setTimeout(()=>{this.container.style.transform=`translateX(${t.x}px) translateY(${t.y}px)`,this.container.style.opacity=1..toString(),"function"==typeof this.options.onOpen&&this.options.onOpen.call(this)},100)};hide=()=>{this.visible&&(this.visible=!1,this.container.removeAttribute("style"),this.container.style.transition=`\n transform ${this.options.duration}ms ease-out,\n opacity ${this.options.duration}ms ease-out`,setTimeout(()=>{this.container.style.transform="translateX(0px) translateY(0px)",this.container.style.opacity="0","function"==typeof this.options.onClose&&this.options.onClose.call(this)},100))}}const L={classList:["modal"],title:null,onOpen:null,onClose:null};class C{el;container;options;visible;footer;constructor(t,e,i){if(this.el=t,this.options={...L,...i},this.container=document.createElement("dialog"),this.container.classList.add("modal","display-modal",this.options.classList.join(" ")),i.title){const t=document.createElement("div");t.classList.add("modal-header"),t.append(i.title),this.container.append(t)}const s=document.createElement("div");s.classList.add("modal-content"),s.append(e),this.container.append(s),this.footer=document.createElement("div"),this.footer.classList.add("modal-footer"),this.container.append(this.footer),document.body.append(this.container),document.addEventListener("click",t=>{this.visible&&this.el!==t.target&&!t.target.closest(".display-modal")&&this.hide()},!0)}static init(t,e,i){return new C(t,e,i)}show=()=>{this.visible||(this.visible=!0,this.container.setAttribute("open","true"),setTimeout(()=>{"function"==typeof this.options.onOpen&&this.options.onOpen.call(this)},10))};hide=()=>{this.visible&&(this.visible=!1,this.container.removeAttribute("open"),setTimeout(()=>{"function"==typeof this.options.onClose&&this.options.onClose.call(this)},10))}}const k={format:"mmm dd, yyyy",parse:null,isDateRange:!1,dateRangeEndEl:null,isMultipleSelection:!1,defaultDate:null,defaultEndDate:null,setDefaultDate:!1,setDefaultEndDate:!1,disableWeekends:!1,disableDayFn:null,firstDay:0,minDate:null,maxDate:null,yearRange:10,minYear:0,maxYear:9999,minMonth:void 0,maxMonth:void 0,startRange:null,endRange:null,isRTL:!1,yearRangeReverse:!1,showMonthAfterYear:!1,showDaysInNextAndPreviousMonths:!1,openByDefault:!1,container:null,showClearBtn:!1,autoSubmit:!0,i18n:{cancel:"Cancel",clear:"Clear",done:"Ok",previousMonth:"‹",nextMonth:"›",months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],weekdaysAbbrev:["S","M","T","W","T","F","S"]},events:[],onSelect:null,onDraw:null,onInputInteraction:null,displayPlugin:null,displayPluginOptions:null,onConfirm:null,onCancel:null};class T extends i{id;multiple=!1;calendarEl;containerEl;yearTextEl;dateTextEl;endDateEl;dateEls;date;endDate;dates;formats;calendars;_y;_m;displayPlugin;footer;static _template;constructor(t,i){super(t,i,T),this.el.M_Datepicker=this,this.options={...T.defaults,...i},i&&i.hasOwnProperty("i18n")&&"object"==typeof i.i18n&&(this.options.i18n={...T.defaults.i18n,...i.i18n}),this.options.minDate&&this.options.minDate.setHours(0,0,0,0),this.options.maxDate&&this.options.maxDate.setHours(0,0,0,0),this.id=e.guid(),this._setupVariables(),this._insertHTMLIntoDOM(),this._setupEventHandlers(),this.options.displayPlugin&&this._setupDisplayPlugin(),this._pickerSetup()}static get defaults(){return k}static init(t,e={}){return super.init(t,e,T)}static _isDate(t){return/Date/.test(Object.prototype.toString.call(t))&&!isNaN(t.getTime())}static _isWeekend(t){const e=t.getDay();return 0===e||6===e}static _setToStartOfDay(t){T._isDate(t)&&t.setHours(0,0,0,0)}static _getDaysInMonth(t,e){return[31,T._isLeapYear(t)?29:28,31,30,31,30,31,31,30,31,30,31][e]}static _isLeapYear(t){return t%4==0&&t%100!=0||t%400==0}static _compareDates(t,e){return t.getTime()===e.getTime()}static _compareWithinRange(t,e,i){return t.getTime()>e.getTime()&&t.getTime()this.formats[e]?this.formats[e](t):e).join("")}setDateFromInput(t){const e=new Date(Date.parse(t.value));this.setDate(e,!1,t==this.endDateEl,!0)}setDate(t=null,e=!1,i=!1,s=!1){const n=this.validateDate(t);n&&(this.options.isMultipleSelection?s||this.setMultiDate(n):this.setSingleDate(n,i),T._setToStartOfDay(n),this.gotoDate(n),e||"function"!=typeof this.options.onSelect||this.options.onSelect.call(this,n))}validateDate(t){if(!t)return this._renderDateDisplay(t),this.draw();if("string"==typeof t&&(t=new Date(Date.parse(t))),!T._isDate(t))return;const e=this.options.minDate,i=this.options.maxDate;return T._isDate(e)&&ti&&(t=i),new Date(t.getTime())}setSingleDate(t,e){e?e&&(this.endDate=t):this.date=t}setMultiDate(t){const e=this.dates?.find(e=>e.getTime()===t.getTime()&&e);e?this.dates.splice(this.dates.indexOf(e),1):this.dates.push(t),this.dates.sort((t,e)=>t.getTime(){if(e>this.dates.length-1)return t}).forEach(t=>{t.remove()}),this.dates.forEach((t,e)=>{if(Array.from(this.dateEls)[e])return void this.setInputValue(this.dateEls[e],t);const i=this.createDateInput();this.setInputValue(i,t),this.dateEls.push(i)})}setInputValue(t,e){"date"==t.type?(this.setDataDate(t,e),t.value=this.formatDate(e,"yyyy-mm-dd")):t.value=this.toString(e),this.el.dispatchEvent(new CustomEvent("change",{bubbles:!0,cancelable:!0,composed:!0,detail:{firedBy:this}}))}_setupDisplayPlugin(){const t={...this.options.displayPluginOptions,onOpen:()=>{document.querySelectorAll(".select-dropdown").forEach(t=>{t.tabIndex=0})},onClose:()=>{document.querySelectorAll(".select-dropdown").forEach(t=>{t.tabIndex=-1})}};"docked"===this.options.displayPlugin&&(this.displayPlugin=b.init(this.el,this.containerEl,t)),"modal"===this.options.displayPlugin&&(this.displayPlugin=C.init(this.el,this.containerEl,{...t,classList:["datepicker-modal"]}),this.footer.remove(),this.footer=this.displayPlugin.footer),this.options.openByDefault&&this.displayPlugin.show()}_renderDateDisplay(t,e=null){const i=T._isDate(t)?t:new Date;if(this.options.isDateRange){const t=T._isDate(e)?e:new Date;this.dateTextEl.innerHTML=`${this.formatDate(i,"mmm d")} - ${this.formatDate(t,"mmm d")}`}else this.dateTextEl.innerHTML=this.formatDate(i,"ddd, mmm d")}gotoDate(t){let e=!0;if(T._isDate(t)){if(this.calendars){const i=new Date(this.calendars[0].year,this.calendars[0].month,1),s=new Date(this.calendars[this.calendars.length-1].year,this.calendars[this.calendars.length-1].month,1),n=t.getTime();s.setMonth(s.getMonth()+1),s.setDate(s.getDate()-1),e=n11&&(t.year+=Math.floor(Math.abs(t.month)/12),t.month-=12),t}nextMonth(){this.calendars[0].month++,this.adjustCalendars()}prevMonth(){this.calendars[0].month--,this.adjustCalendars()}render(t,e,i){const s=new Date,n=T._getDaysInMonth(t,e),o=[];let a=new Date(t,e,1).getDay(),l=[];T._setToStartOfDay(s),this.options.firstDay>0&&(a-=this.options.firstDay,a<0&&(a+=7));const r=0===e?11:e-1,h=11===e?0:e+1,d=0===e?t-1:t,c=11===e?t+1:t,p=T._getDaysInMonth(d,r);let u=n+a,m=u;for(;m>7;)m-=7;u+=7-m;let v=!1;for(let i=0,m=0;i=n+a,f=this.options.startRange&&T._compareDates(this.options.startRange,u),E=this.options.endRange&&T._compareDates(this.options.endRange,u),w=this.options.startRange&&this.options.endRange&&this.options.startRangethis.options.maxDate||this.options.disableWeekends&&T._isWeekend(u)||this.options.disableDayFn&&this.options.disableDayFn(u),L=this.options.isDateRange&&this.date&&this.endDate&&T._compareDates(this.date,u),C=this.options.isDateRange&&this.endDate&&T._compareDates(this.endDate,u),k=this.options.isDateRange&&T._isDate(this.endDate)&&T._compareWithinRange(u,this.date,this.endDate);let D=i-a+1,x=e,S=t,I=!1;T._isDate(this.date)&&(I=T._compareDates(u,this.date)),!I&&T._isDate(this.endDate)&&(I=T._compareDates(u,this.endDate)),this.options.isMultipleSelection&&this.dates?.some(t=>t.getTime()===u.getTime())&&(I=!0),y&&(i!(!t.hasOwnProperty(e)||!0!==t[e])).length),s=["datepicker-day"];if(t.isEmpty){if(!t.showDaysInNextAndPreviousMonths)return'';s.push("is-outside-current-month"),s.push("is-selection-disabled")}for(const[i,n]of Object.entries(e))t.hasOwnProperty(i)&&t[i]&&s.push(n);return``}renderRow(t,e,i){return''+(e?t.reverse():t).join("")+""}renderTable(t,e,i){return'
'+this.renderHead(t)+this.renderBody(e)+"
"}renderHead(t){const e=[];let i;for(i=0;i<7;i++)e.push(`${this.renderDayName(t,i,!0)}`);return""+(t.isRTL?e.reverse():e).join("")+""}renderBody(t){return""+t.join("")+""}renderTitle(t,e,i,s,n,o){const a=this.options,l=i===a.minYear,r=i===a.maxYear;let h,d,c=[],p='
',u=!0,m=!0;for(h=0;h<12;h++)c.push('");const v='";for(Array.isArray(a.yearRange)?(h=a.yearRange[0],d=a.yearRange[1]+1):(h=i-a.yearRange,d=1+i+a.yearRange),c=[];h=a.minYear&&c.push(``);a.yearRangeReverse&&c.reverse();const g=``;p+=``,p+='
',a.showMonthAfterYear?p+=g+v:p+=v+g,p+="
",l&&(0===s||a.minMonth>=s)&&(u=!1),r&&(11===s||a.maxMonth<=s)&&(m=!1);return p+=``,p+"
"}draw(){const t=this.options,e=t.minYear,i=t.maxYear,s=t.minMonth,n=t.maxMonth;let o="";this._y<=e&&(this._y=e,!isNaN(s)&&this._m=i&&(this._y=i,!isNaN(n)&&this._m>n&&(this._m=n));const a="datepicker-title-"+Math.random().toString(36).replace(/[^a-z]+/g,"").substr(0,2);for(let t=0;t<1;t++)this.options.isDateRange?this._renderDateDisplay(this.date,this.endDate):this._renderDateDisplay(this.date),o+=this.renderTitle(this,t,this.calendars[t].year,this.calendars[t].month,this.calendars[0].year,a)+this.render(this.calendars[t].year,this.calendars[t].month,a);this.destroySelects(),this.calendarEl.innerHTML=o;const l=this.calendarEl.querySelector(".orig-select-year"),r=this.calendarEl.querySelector(".orig-select-month");E.init(l,{classes:"select-year",dropdownOptions:{container:document.body,constrainWidth:!1}}),E.init(r,{classes:"select-month",dropdownOptions:{container:document.body,constrainWidth:!1}}),l.addEventListener("change",this._handleYearChange),r.addEventListener("change",this._handleMonthChange),"function"==typeof this.options.onDraw&&this.options.onDraw.call(this)}_setupEventHandlers(){this.el.addEventListener("click",this._handleInputClick),this.el.addEventListener("keydown",this._handleInputKeydown),this.el.addEventListener("change",this._handleInputChange),this.calendarEl.addEventListener("click",this._handleCalendarClick)}_setupVariables(){const t=document.createElement("template");t.innerHTML=T._template.trim(),this.containerEl=t.content.firstChild,this.calendarEl=this.containerEl.querySelector(".datepicker-calendar"),this.yearTextEl=this.containerEl.querySelector(".year-text"),this.dateTextEl=this.containerEl.querySelector(".date-text"),this.footer=this.containerEl.querySelector(".datepicker-footer"),this.formats={d:t=>t.getDate(),dd:t=>{const e=t.getDate();return(e<10?"0":"")+e},ddd:t=>this.options.i18n.weekdaysShort[t.getDay()],dddd:t=>this.options.i18n.weekdays[t.getDay()],m:t=>t.getMonth()+1,mm:t=>{const e=t.getMonth()+1;return(e<10?"0":"")+e},mmm:t=>this.options.i18n.monthsShort[t.getMonth()],mmmm:t=>this.options.i18n.months[t.getMonth()],yy:t=>(""+t.getFullYear()).slice(2),yyyy:t=>t.getFullYear()}}_pickerSetup(){this.options.defaultDate||(this.options.defaultDate=new Date(Date.parse(this.el.value)));const t=this.options.defaultDate;if(T._isDate(t)?this.options.setDefaultDate?(this.setDate(t,!0),this.setInputValue(this.el,t)):this.gotoDate(t):this.gotoDate(new Date),this.options.isDateRange){this.multiple=!0;const t=this.options.defaultEndDate;T._isDate(t)&&this.options.setDefaultEndDate&&(this.setDate(t,!0,!0),this.setInputValue(this.endDateEl,t))}this.options.isMultipleSelection&&(this.multiple=!0,this.dates=[],this.dateEls=[],this.dateEls.push(this.el))}_removeEventHandlers(){this.el.removeEventListener("click",this._handleInputClick),this.el.removeEventListener("keydown",this._handleInputKeydown),this.el.removeEventListener("change",this._handleInputChange),this.calendarEl.removeEventListener("click",this._handleCalendarClick),this.options.isDateRange&&(this.endDateEl.removeEventListener("click",this._handleInputClick),this.endDateEl.removeEventListener("keypress",this._handleInputKeydown),this.endDateEl.removeEventListener("change",this._handleInputChange))}_handleInputClick=t=>{"date"==t.type&&t.preventDefault(),this.setDateFromInput(t.target),this.draw(),this.gotoDate(t.target===this.el?this.date:this.endDate),this.displayPlugin&&this.displayPlugin.show(),this.options.onInputInteraction&&this.options.onInputInteraction.call(this)};_handleInputKeydown=t=>{e.keys.ENTER.includes(t.key)&&(t.preventDefault(),this.setDateFromInput(t.target),this.draw(),this.displayPlugin&&this.displayPlugin.show(),this.options.onInputInteraction&&this.options.onInputInteraction.call(this))};_handleCalendarClick=t=>{const e=t.target;if(!e.classList.contains("is-disabled"))if(!e.classList.contains("datepicker-day-button")||e.classList.contains("is-empty")||e.parentElement.classList.contains("is-disabled"))e.closest(".month-prev")?this.prevMonth():e.closest(".month-next")&&this.nextMonth();else{const e=new Date(t.target.getAttribute("data-year"),t.target.getAttribute("data-month"),t.target.getAttribute("data-day"));if((!this.multiple||this.multiple&&this.options.isMultipleSelection)&&this.setDate(e),this.options.isDateRange){const t=T._isDate(this.date)&&this.options.autoSubmit;this._handleDateRangeCalendarClick(e),t&&this._confirm()}!this.options.isDateRange&&this.options.autoSubmit&&this._confirm()}};_handleDateRangeCalendarClick=t=>{if(null!=this.endDate&&T._compareDates(t,this.endDate))this._clearDates(),this.draw();else{if(T._isDate(this.date)&&T._comparePastDate(t,this.date))return;this.setDate(t,!0,T._isDate(this.date))}};_handleClearClick=()=>{this._clearDates(),this.setInputValues()};_clearDates=()=>{this.date=null,this.endDate=null,this.draw()};_handleMonthChange=t=>{this.gotoMonth(t.target.value)};_handleYearChange=t=>{this.gotoYear(t.target.value)};gotoMonth(t){isNaN(t)||(this.calendars[0].month=parseInt(t,10),this.adjustCalendars())}gotoYear(t){isNaN(t)||(this.calendars[0].year=parseInt(t,10),this.adjustCalendars())}_handleInputChange=t=>{let e;const i=t.target;t.detail?.firedBy!==this&&(i!=this.endDateEl||this.date)&&(e=this.options.parse?this.options.parse(t.target.value,"function"==typeof this.options.format?this.options.format(new Date(this.el.value)):this.options.format):new Date(Date.parse(t.target.value)),T._isDate(e)&&(this.setDate(e,!1,i==this.endDateEl,!0),"date"==t.type&&(this.setDataDate(t,e),this.setInputValues())))};renderDayName(t,e,i=!1){for(e+=t.firstDay;e>=7;)e-=7;return i?t.i18n.weekdaysAbbrev[e]:t.i18n.weekdays[e]}createDateInput(){const t=this.el.cloneNode(!0);return t.addEventListener("click",this._handleInputClick),t.addEventListener("keypress",this._handleInputKeydown),t.addEventListener("change",this._handleInputChange),this.el.parentElement.appendChild(t),t}_finishSelection=()=>{this.setInputValues()};_confirm=()=>{this._finishSelection(),this.displayPlugin&&this.displayPlugin.hide(),"function"==typeof this.options.onConfirm&&this.options.onConfirm.call(this)};_cancel=()=>{this.displayPlugin&&this.displayPlugin.hide(),"function"==typeof this.options.onCancel&&this.options.onCancel.call(this)};open(){return console.warn("Datepicker.open() is deprecated. Remove this method and wrap in modal yourself."),this}close(){return console.warn("Datepicker.close() is deprecated. Remove this method and wrap in modal yourself."),this}static{T._template='\n
\n
\n \n \n
\n
\n
\n \n
\n
'}}class D{static validateField(t){if(!t)return void console.error("No text field element found");const e=null!==t.getAttribute("data-length"),i=parseInt(t.getAttribute("data-length")),s=t.value.length;0===s&&!1===t.validity.badInput&&!t.required&&t.classList.contains("validate")?t.classList.remove("invalid"):t.classList.contains("validate")&&(t.validity.valid&&e&&s<=i||t.validity.valid&&!e?t.classList.remove("invalid"):t.classList.add("invalid"))}static textareaAutoResize(t){const e=t;let i=document.querySelector(".hiddendiv");i||(i=document.createElement("div"),i.classList.add("hiddendiv","common"),document.body.append(i));const s=getComputedStyle(e),n=s.fontFamily,o=s.fontSize,a=s.lineHeight,l=s.paddingTop,r=s.paddingRight,h=s.paddingBottom,d=s.paddingLeft;o&&(i.style.fontSize=o),n&&(i.style.fontFamily=n),a&&(i.style.lineHeight=a),l&&(i.style.paddingTop=l),r&&(i.style.paddingRight=r),h&&(i.style.paddingBottom=h),d&&(i.style.paddingLeft=d),e.hasAttribute("original-height")||e.setAttribute("original-height",e.getBoundingClientRect().height.toString()),"off"===e.getAttribute("wrap")&&(i.style.overflowWrap="normal",i.style.whiteSpace="pre"),i.innerText=e.value+"\n",i.innerHTML=i.innerHTML.replace(/\n/g,"
"),e.offsetWidth>0&&e.offsetHeight>0?i.style.width=e.getBoundingClientRect().width+"px":i.style.width=window.innerWidth/2+"px";const c=parseInt(e.getAttribute("original-height")),p=parseInt(e.getAttribute("previous-length"));isNaN(c)||(c<=i.clientHeight?e.style.height=i.clientHeight+"px":e.value.length{document.addEventListener("change",t=>{const e=t.target;if(e instanceof HTMLInputElement){if(0!==e.value.length||null!==e.getAttribute("placeholder"))for(const t of e.parentNode.children)"label"==t.tagName&&t.classList.add("active");D.validateField(e)}}),document.addEventListener("keyup",t=>{const i=t.target;i instanceof HTMLInputElement&&["radio","checkbox"].includes(i.type)&&e.keys.TAB.includes(t.key)&&(i.classList.add("tabbed"),i.addEventListener("blur",()=>i.classList.remove("tabbed"),{once:!0}))}),document.querySelectorAll(".materialize-textarea").forEach(t=>{D.InitTextarea(t)}),document.querySelectorAll('.file-field input[type="file"]').forEach(t=>{D.InitFileInputPath(t)})})}static InitTextarea(t){t.setAttribute("original-height",t.getBoundingClientRect().height.toString()),t.setAttribute("previous-length",(t.value||"").length.toString()),D.textareaAutoResize(t),t.addEventListener("keyup",t=>D.textareaAutoResize(t.target)),t.addEventListener("keydown",t=>D.textareaAutoResize(t.target))}static InitFileInputPath(t){t.addEventListener("change",()=>{const e=t.closest(".file-field").querySelector("input.file-path"),i=t.files,s=[];for(let t=0;t{this._handleMaterialboxToggle()};_handleMaterialboxKeypress=t=>{e.keys.ENTER.includes(t.key)&&this._handleMaterialboxToggle()};_handleMaterialboxToggle=()=>{!1===this.doneAnimating||this.overlayActive&&this.doneAnimating?this.close():this.open()};_handleWindowScroll=()=>{this.overlayActive&&this.close()};_handleWindowResize=()=>{this.overlayActive&&this.close()};_handleWindowEscape=t=>{e.keys.ESC.includes(t.key)&&this.doneAnimating&&this.overlayActive&&this.close()};_makeAncestorsOverflowVisible(){this._changedAncestorList=[];let t=this.placeholder.parentNode;for(;null!==t&&t!==document;){const e=t;"visible"!==e.style.overflow&&(e.style.overflow="visible",this._changedAncestorList.push(e)),t=t.parentNode}}_offset(t){const e=t.getBoundingClientRect(),i=document.documentElement;return{top:e.top+window.scrollY-i.clientTop,left:e.left+window.scrollX-i.clientLeft}}_updateVars(){this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight,this.caption=this.el.getAttribute("data-caption")||""}_animateImageIn(){this.el.style.maxHeight=this.newHeight.toString()+"px",this.el.style.maxWidth=this.newWidth.toString()+"px";const t=this.options.inDuration;this.el.style.transition="none",this.el.style.height=this.originalHeight+"px",this.el.style.width=this.originalWidth+"px",setTimeout(()=>{this.el.style.transition=`height ${t}ms ease,\n width ${t}ms ease,\n left ${t}ms ease,\n top ${t}ms ease\n `,this.el.style.height=this.newHeight+"px",this.el.style.width=this.newWidth+"px",this.el.style.left=e.getDocumentScrollLeft()+this.windowWidth/2-this._offset(this.placeholder).left-this.newWidth/2+"px",this.el.style.top=e.getDocumentScrollTop()+this.windowHeight/2-this._offset(this.placeholder).top-this.newHeight/2+"px"},1),setTimeout(()=>{this.doneAnimating=!0,"function"==typeof this.options.onOpenEnd&&this.options.onOpenEnd.call(this,this.el)},t)}_animateImageOut(){const t=this.options.outDuration;this.el.style.transition=`height ${t}ms ease,\n width ${t}ms ease,\n left ${t}ms ease,\n top ${t}ms ease\n `,this.el.style.height=this.originalWidth+"px",this.el.style.width=this.originalWidth+"px",this.el.style.left="0",this.el.style.top="0",setTimeout(()=>{this.placeholder.style.height="",this.placeholder.style.width="",this.placeholder.style.position="",this.placeholder.style.top="",this.placeholder.style.left="",this.attrWidth&&this.el.setAttribute("width",this.attrWidth.toString()),this.attrHeight&&this.el.setAttribute("height",this.attrHeight.toString()),this.el.removeAttribute("style"),this.originInlineStyles&&this.el.setAttribute("style",this.originInlineStyles),this.el.classList.remove("active"),this.doneAnimating=!0,this._changedAncestorList.forEach(t=>t.style.overflow=""),"function"==typeof this.options.onCloseEnd&&this.options.onCloseEnd.call(this,this.el)},t)}_addCaption(){this._photoCaption=document.createElement("div"),this._photoCaption.classList.add("materialbox-caption"),this._photoCaption.innerText=this.caption,document.body.append(this._photoCaption),this._photoCaption.style.display="inline",this._photoCaption.style.transition="none",this._photoCaption.style.opacity="0";const t=this.options.inDuration;setTimeout(()=>{this._photoCaption.style.transition=`opacity ${t}ms ease`,this._photoCaption.style.opacity="1"},1)}_removeCaption(){const t=this.options.outDuration;this._photoCaption.style.transition=`opacity ${t}ms ease`,this._photoCaption.style.opacity="0",setTimeout(()=>{this._photoCaption.remove()},t)}_addOverlay(){this._overlay=document.createElement("div"),this._overlay.id="materialbox-overlay",this._overlay.addEventListener("click",()=>{this.doneAnimating&&this.close()},{once:!0}),this.el.before(this._overlay);const t=this._overlay.getBoundingClientRect();this._overlay.style.width=this.windowWidth+"px",this._overlay.style.height=this.windowHeight+"px",this._overlay.style.left=-1*t.left+"px",this._overlay.style.top=-1*t.top+"px",this._overlay.style.transition="none",this._overlay.style.opacity="0";const e=this.options.inDuration;setTimeout(()=>{this._overlay.style.transition=`opacity ${e}ms ease`,this._overlay.style.opacity="1"},1)}_removeOverlay(){const t=this.options.outDuration;this._overlay.style.transition=`opacity ${t}ms ease`,this._overlay.style.opacity="0",setTimeout(()=>{this.overlayActive=!1,this._overlay.remove()},t)}open=()=>{this._updateVars(),this.originalWidth=this.el.getBoundingClientRect().width,this.originalHeight=this.el.getBoundingClientRect().height,this.doneAnimating=!1,this.el.classList.add("active"),this.overlayActive=!0,"function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,this.el),this.placeholder.style.width=this.placeholder.getBoundingClientRect().width+"px",this.placeholder.style.height=this.placeholder.getBoundingClientRect().height+"px",this.placeholder.style.position="relative",this.placeholder.style.top="0",this.placeholder.style.left="0",this._makeAncestorsOverflowVisible(),this.el.style.position="absolute",this.el.style.zIndex="1000",this.el.style.willChange="left, top, width, height",this.attrWidth=this.el.getAttribute("width"),this.attrHeight=this.el.getAttribute("height"),this.attrWidth&&(this.el.style.width=this.attrWidth+"px",this.el.removeAttribute("width")),this.attrHeight&&(this.el.style.width=this.attrHeight+"px",this.el.removeAttribute("height")),this._addOverlay(),""!==this.caption&&this._addCaption();const t=this.originalWidth/this.windowWidth,e=this.originalHeight/this.windowHeight;if(this.newWidth=0,this.newHeight=0,t>e){const t=this.originalHeight/this.originalWidth;this.newWidth=.9*this.windowWidth,this.newHeight=.9*this.windowWidth*t}else{const t=this.originalWidth/this.originalHeight;this.newWidth=.9*this.windowHeight*t,this.newHeight=.9*this.windowHeight}this._animateImageIn(),window.addEventListener("scroll",this._handleWindowScroll),window.addEventListener("resize",this._handleWindowResize),window.addEventListener("keyup",this._handleWindowEscape)};close=()=>{this._updateVars(),this.doneAnimating=!1,"function"==typeof this.options.onCloseStart&&this.options.onCloseStart.call(this,this.el),window.removeEventListener("scroll",this._handleWindowScroll),window.removeEventListener("resize",this._handleWindowResize),window.removeEventListener("keyup",this._handleWindowEscape),this._removeOverlay(),this._animateImageOut(),""!==this.caption&&this._removeCaption()}}const I={opacity:.5,inDuration:250,outDuration:250,onOpenStart:null,onOpenEnd:null,onCloseStart:null,onCloseEnd:null,preventScrolling:!0,dismissible:!0,startingTop:"4%",endingTop:"10%"};class A extends i{constructor(t,e){super(t,e,A),this.el.M_Modal=this,this.options={...A.defaults,...e},this.el.tabIndex=0,this._setupEventHandlers()}static get defaults(){return I}static init(t,e={}){return super.init(t,e,A)}static getInstance(t){return t.M_Modal}destroy(){}_setupEventHandlers(){}_removeEventHandlers(){}_handleTriggerClick(){}_handleOverlayClick(){}_handleModalCloseClick(){}_handleKeydown(){}_handleFocus(){}open(){return this}close(){return this}static#$(t){return`\n ${t.header?'":""}\n \n ${t.header?'":""}\n `}static#N(t){const e=document.createElement("dialog");return e.id=t.id,e}static create(t){return this.#N(t)}}const M={edge:"left",draggable:!0,dragTargetWidth:"10px",inDuration:250,outDuration:200,onOpenStart:null,onOpenEnd:null,onCloseStart:null,onCloseEnd:null,preventScrolling:!0};class O extends i{id;isOpen;isFixed;isDragged;lastWindowWidth;lastWindowHeight;static _sidenavs;_overlay;dragTarget;_startingXpos;_xPos;_time;_width;_initialScrollTop;_verticallyScrolling;deltaX;velocityX;percentOpen;constructor(t,e){super(t,e,O),this.el.M_Sidenav=this,this.options={...O.defaults,...e},this.id=this.el.id,this.isOpen=!1,this.isFixed=this.el.classList.contains("sidenav-fixed"),this.isDragged=!1,this.lastWindowWidth=window.innerWidth,this.lastWindowHeight=window.innerHeight,this._createOverlay(),this._createDragTarget(),this._setupEventHandlers(),this._setupClasses(),this._setupFixed(),O._sidenavs.push(this)}static get defaults(){return M}static init(t,e={}){return super.init(t,e,O)}static getInstance(t){return t.M_Sidenav}destroy(){this._removeEventHandlers(),this._enableBodyScrolling(),this._overlay.parentNode.removeChild(this._overlay),this.dragTarget.parentNode.removeChild(this.dragTarget),this.el.M_Sidenav=void 0,this.el.style.transform="";const t=O._sidenavs.indexOf(this);t>=0&&O._sidenavs.splice(t,1)}_createOverlay(){this._overlay=document.createElement("div"),this._overlay.classList.add("sidenav-overlay"),this._overlay.addEventListener("click",this.close),document.body.appendChild(this._overlay)}_setupEventHandlers(){0===O._sidenavs.length&&document.body.addEventListener("click",this._handleTriggerClick);this.dragTarget.addEventListener("touchmove",this._handleDragTargetDrag,null),this.dragTarget.addEventListener("touchend",this._handleDragTargetRelease),this._overlay.addEventListener("touchmove",this._handleCloseDrag,null),this._overlay.addEventListener("touchend",this._handleCloseRelease),this.el.addEventListener("touchmove",this._handleCloseDrag),this.el.addEventListener("touchend",this._handleCloseRelease),this.el.addEventListener("click",this._handleCloseTriggerClick),this.isFixed&&window.addEventListener("resize",this._handleWindowResize),this._setAriaHidden(),this._setTabIndex()}_removeEventHandlers(){1===O._sidenavs.length&&document.body.removeEventListener("click",this._handleTriggerClick),this.dragTarget.removeEventListener("touchmove",this._handleDragTargetDrag),this.dragTarget.removeEventListener("touchend",this._handleDragTargetRelease),this._overlay.removeEventListener("touchmove",this._handleCloseDrag),this._overlay.removeEventListener("touchend",this._handleCloseRelease),this.el.removeEventListener("touchmove",this._handleCloseDrag),this.el.removeEventListener("touchend",this._handleCloseRelease),this.el.removeEventListener("click",this._handleCloseTriggerClick),this.isFixed&&window.removeEventListener("resize",this._handleWindowResize)}_handleTriggerClick(t){const i=t.target.closest(".sidenav-trigger");if(t.target&&i){const s=e.getIdFromTrigger(i),n=document.getElementById(s).M_Sidenav;n&&n.open(),t.preventDefault()}}_startDrag(t){const i=t.targetTouches[0].clientX;this.isDragged=!0,this._startingXpos=i,this._xPos=this._startingXpos,this._time=Date.now(),this._width=this.el.getBoundingClientRect().width,this._overlay.style.display="block",this._initialScrollTop=this.isOpen?this.el.scrollTop:e.getDocumentScrollTop(),this._verticallyScrolling=!1}_dragMoveUpdate(t){const i=t.targetTouches[0].clientX,s=this.isOpen?this.el.scrollTop:e.getDocumentScrollTop();this.deltaX=Math.abs(this._xPos-i),this._xPos=i,this.velocityX=this.deltaX/(Date.now()-this._time),this._time=Date.now(),this._initialScrollTop!==s&&(this._verticallyScrolling=!0)}_handleDragTargetDrag=t=>{if(!this._isDraggable())return;let e=this._calculateDelta(t);const i=e>0?"right":"left";e=Math.min(this._width,Math.abs(e)),this.options.edge===i&&(e=0);let s=e,n="translateX(-100%)";"right"===this.options.edge&&(n="translateX(100%)",s=-s),this.percentOpen=Math.min(1,e/this._width),this.el.style.transform=`${n} translateX(${s}px)`,this._overlay.style.opacity=this.percentOpen.toString()};_handleDragTargetRelease=()=>{this.isDragged&&(this.percentOpen>.2?this.open():this._animateOut(),this.isDragged=!1,this._verticallyScrolling=!1)};_handleCloseDrag=t=>{if(!this.isOpen||!this._isDraggable())return;let e=this._calculateDelta(t);const i=e>0?"right":"left";e=Math.min(this._width,Math.abs(e)),this.options.edge!==i&&(e=0);let s=-e;"right"===this.options.edge&&(s=-s),this.percentOpen=Math.min(1,1-e/this._width),this.el.style.transform=`translateX(${s}px)`,this._overlay.style.opacity=this.percentOpen.toString()};_calculateDelta=t=>(this.isDragged||this._startDrag(t),this._dragMoveUpdate(t),this._xPos-this._startingXpos);_handleCloseRelease=()=>{this.isOpen&&this.isDragged&&(this.percentOpen>.8?this._animateIn():this.close(),this.isDragged=!1,this._verticallyScrolling=!1)};_handleCloseTriggerClick=t=>{t.target.closest(".sidenav-close")&&!this._isCurrentlyFixed()&&this.close()};_handleWindowResize=()=>{this.lastWindowWidth!==window.innerWidth&&(window.innerWidth>992?this.open():this.close()),this.lastWindowWidth=window.innerWidth,this.lastWindowHeight=window.innerHeight};_setupClasses(){"right"===this.options.edge&&(this.el.classList.add("right-aligned"),this.dragTarget.classList.add("right-aligned"))}_removeClasses(){this.el.classList.remove("right-aligned"),this.dragTarget.classList.remove("right-aligned")}_setupFixed(){this._isCurrentlyFixed()&&this.open()}_isDraggable(){return this.options.draggable&&!this._isCurrentlyFixed()&&!this._verticallyScrolling}_isCurrentlyFixed(){return this.isFixed&&window.innerWidth>992}_createDragTarget(){const t=document.createElement("div");t.classList.add("drag-target"),t.style.width=this.options.dragTargetWidth,document.body.appendChild(t),this.dragTarget=t}_preventBodyScrolling(){document.body.style.overflow="hidden"}_enableBodyScrolling(){document.body.style.overflow=""}open=()=>{!0!==this.isOpen&&(this.isOpen=!0,"function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,this.el),this._isCurrentlyFixed()?(this.el.style.transform="translateX(0)",this._enableBodyScrolling(),this._overlay.style.display="none"):(this.options.preventScrolling&&this._preventBodyScrolling(),this.isDragged&&1==this.percentOpen||this._animateIn(),this._setAriaHidden(),this._setTabIndex()))};close=()=>{if(!1!==this.isOpen)if(this.isOpen=!1,"function"==typeof this.options.onCloseStart&&this.options.onCloseStart.call(this,this.el),this._isCurrentlyFixed()){const t="left"===this.options.edge?"-105%":"105%";this.el.style.transform=`translateX(${t})`}else this._enableBodyScrolling(),this.isDragged&&0==this.percentOpen?this._overlay.style.display="none":this._animateOut(),this._setAriaHidden(),this._setTabIndex()};_animateIn(){this._animateSidenavIn(),this._animateOverlayIn()}_animateOut(){this._animateSidenavOut(),this._animateOverlayOut()}_animateSidenavIn(){let t="left"===this.options.edge?-1:1;this.isDragged&&(t="left"===this.options.edge?t+this.percentOpen:t-this.percentOpen);const e=this.options.inDuration;this.el.style.transition="none",this.el.style.transform="translateX("+100*t+"%)",setTimeout(()=>{this.el.style.transition=`transform ${e}ms ease`,this.el.style.transform="translateX(0)"},1),setTimeout(()=>{"function"==typeof this.options.onOpenEnd&&this.options.onOpenEnd.call(this,this.el)},e)}_animateSidenavOut(){const t="left"===this.options.edge?-1:1,e=this.options.outDuration;this.el.style.transition=`transform ${e}ms ease`,this.el.style.transform="translateX("+100*t+"%)",setTimeout(()=>{"function"==typeof this.options.onCloseEnd&&this.options.onCloseEnd.call(this,this.el)},e)}_animateOverlayIn(){let t=0;this.isDragged?t=this.percentOpen:this._overlay.style.display="block";const e=this.options.inDuration;this._overlay.style.transition="none",this._overlay.style.opacity=t.toString(),setTimeout(()=>{this._overlay.style.transition=`opacity ${e}ms ease`,this._overlay.style.opacity="1"},1)}_animateOverlayOut(){const t=this.options.outDuration;this._overlay.style.transition=`opacity ${t}ms ease`,this._overlay.style.opacity="0",setTimeout(()=>{this._overlay.style.display="none"},t)}_setAriaHidden=()=>{this.el.ariaHidden=this.isOpen?"false":"true";const t=document.querySelector(".nav-wrapper ul");t&&(t.ariaHidden=this.isOpen.toString())};_setTabIndex=()=>{const t=document.querySelectorAll(".nav-wrapper ul li a"),e=document.querySelectorAll(".sidenav li a");t&&t.forEach(t=>{t.tabIndex=this.isOpen?-1:0}),e&&e.forEach(t=>{t.tabIndex=this.isOpen?0:-1})};static{O._sidenavs=[]}}const R={indicators:!0,height:400,duration:500,interval:6e3,pauseOnFocus:!0,pauseOnHover:!0,indicatorLabelFunc:null};class H extends i{activeIndex;interval;eventPause;_slider;_slides;_activeSlide;_indicators;_hovered;_focused;_focusCurrent;_sliderId;constructor(t,i){super(t,i,H),this.el.M_Slider=this,this.options={...H.defaults,...i},this.interval=null,this.eventPause=!1,this._hovered=!1,this._focused=!1,this._focusCurrent=!1,this._slider=this.el.querySelector(".slides"),this._slides=Array.from(this._slider.querySelectorAll("li")),this.activeIndex=this._slides.findIndex(t=>t.classList.contains("active")),-1!==this.activeIndex&&(this._activeSlide=this._slides[this.activeIndex]),this._setSliderHeight(),this._slider.hasAttribute("id")?this._sliderId=this._slider.getAttribute("id"):(this._sliderId="slider-"+e.guid(),this._slider.setAttribute("id",this._sliderId));const s="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";this._slides.forEach(t=>{const e=t.querySelector("img");e&&e.src!==s&&(e.style.backgroundImage="url("+e.src+")",e.src=s),t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1"),t.style.visibility="hidden"}),this._setupIndicators(),this._activeSlide?(this._activeSlide.style.display="block",this._activeSlide.style.visibility="visible"):(this.activeIndex=0,this._slides[0].classList.add("active"),this._slides[0].style.visibility="visible",this._activeSlide=this._slides[0],this._animateSlide(this._slides[0],!0),this.options.indicators&&this._indicators[this.activeIndex].children[0].classList.add("active")),this._setupEventHandlers(),this.start()}static get defaults(){return R}static init(t,e={}){return super.init(t,e,H)}static getInstance(t){return t.M_Slider}destroy(){this.pause(),this._removeIndicators(),this._removeEventHandlers(),this.el.M_Slider=void 0}_setupEventHandlers(){this.options.pauseOnFocus&&(this.el.addEventListener("focusin",this._handleAutoPauseFocus),this.el.addEventListener("focusout",this._handleAutoStartFocus)),this.options.pauseOnHover&&(this.el.addEventListener("mouseenter",this._handleAutoPauseHover),this.el.addEventListener("mouseleave",this._handleAutoStartHover)),this.options.indicators&&this._indicators.forEach(t=>{t.addEventListener("click",this._handleIndicatorClick)})}_removeEventHandlers(){this.options.pauseOnFocus&&(this.el.removeEventListener("focusin",this._handleAutoPauseFocus),this.el.removeEventListener("focusout",this._handleAutoStartFocus)),this.options.pauseOnHover&&(this.el.removeEventListener("mouseenter",this._handleAutoPauseHover),this.el.removeEventListener("mouseleave",this._handleAutoStartHover)),this.options.indicators&&this._indicators.forEach(t=>{t.removeEventListener("click",this._handleIndicatorClick)})}_handleIndicatorClick=t=>{const e=t.target.parentElement,i=[...e.parentNode.children].indexOf(e);this._focusCurrent=!0,this.set(i)};_handleAutoPauseHover=()=>{this._hovered=!0,null!=this.interval&&this._pause(!0)};_handleAutoPauseFocus=()=>{this._focused=!0,null!=this.interval&&this._pause(!0)};_handleAutoStartHover=()=>{this._hovered=!1,this.options.pauseOnFocus&&this._focused||!this.eventPause||this.start()};_handleAutoStartFocus=()=>{this._focused=!1,this.options.pauseOnHover&&this._hovered||!this.eventPause||this.start()};_handleInterval=()=>{const t=this._slider.querySelector(".active");let e=[...t.parentNode.children].indexOf(t);this._slides.length===e+1?e=0:e+=1,this.set(e)};_animateSlide(t,e){let i=0,s=0;t.style.opacity=e?"0":"1",setTimeout(()=>{t.style.transition=`opacity ${this.options.duration}ms ease`,t.style.opacity=e?"1":"0"},1);const n=t.querySelector(".caption");n&&(n.classList.contains("center-align")?s=-100:n.classList.contains("right-align")?i=100:n.classList.contains("left-align")&&(i=-100),n.style.opacity=e?"0":"1",n.style.transform=e?`translate(${i}px, ${s}px)`:"translate(0, 0)",setTimeout(()=>{n.style.transition=`opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`,n.style.opacity=e?"1":"0",n.style.transform=e?"translate(0, 0)":`translate(${i}px, ${s}px)`},this.options.duration))}_setSliderHeight(){this.el.classList.contains("fullscreen")||(this.options.indicators?this.el.style.height=this.options.height+40+"px":this.el.style.height=this.options.height+"px",this._slider.style.height=this.options.height+"px")}_setupIndicators(){if(this.options.indicators){const t=document.createElement("ul");t.classList.add("indicators");const e=[];this._slides.forEach((i,s)=>{const n=this.options.indicatorLabelFunc?this.options.indicatorLabelFunc.call(this,s+1,0===s):`${s+1}`,o=document.createElement("li");o.classList.add("indicator-item"),o.innerHTML=``,e.push(o),t.append(o)}),this.el.append(t),this._indicators=e}}_removeIndicators(){this.el.querySelector("ul.indicators").remove()}set(t){if(t>=this._slides.length?t=0:t<0&&(t=this._slides.length-1),this.activeIndex===t)return;this._activeSlide=this._slides[this.activeIndex];const e=this._activeSlide.querySelector(".caption");if(this._activeSlide.classList.remove("active"),this._slides.forEach(t=>t.style.visibility="visible"),this._activeSlide.style.opacity="0",setTimeout(()=>{this._slides.forEach(t=>{t.classList.contains("active")||(t.style.opacity="0",t.style.transform="translate(0, 0)",t.style.visibility="hidden")})},this.options.duration),e.style.opacity="0",this.options.indicators){const e=this._indicators[this.activeIndex].children[0],i=this._indicators[t].children[0];e.classList.remove("active"),i.classList.add("active"),"function"==typeof this.options.indicatorLabelFunc&&(e.ariaLabel=this.options.indicatorLabelFunc.call(this,this.activeIndex,!1),i.ariaLabel=this.options.indicatorLabelFunc.call(this,t,!0))}this._animateSlide(this._slides[t],!0),this._slides[t].classList.add("active"),this.activeIndex=t,null!=this.interval&&this.start()}_pause(t){clearInterval(this.interval),this.eventPause=t,this.interval=null}pause=()=>{this._pause(!1)};start=()=>{clearInterval(this.interval),this.interval=setInterval(this._handleInterval,this.options.duration+this.options.interval),this.eventPause=!1};next=()=>{let t=this.activeIndex+1;t>=this._slides.length?t=0:t<0&&(t=this._slides.length-1),this.set(t)};prev=()=>{let t=this.activeIndex-1;t>=this._slides.length?t=0:t<0&&(t=this._slides.length-1),this.set(t)}}const P={duration:300,onShow:null,swipeable:!1,responsiveThreshold:1/0};class W extends i{_tabLinks;_index;_indicator;_tabWidth;_tabsWidth;_tabsCarousel;_activeTabLink;_content;constructor(t,e){super(t,e,W),this.el.M_Tabs=this,this.options={...W.defaults,...e},this._tabLinks=this.el.querySelectorAll("li.tab > a"),this._index=0,this._setupActiveTabLink(),this.options.swipeable?this._setupSwipeableTabs():this._setupNormalTabs(),this._setTabsAndTabWidth(),this._createIndicator(),this._setupEventHandlers()}static get defaults(){return P}static init(t,e={}){return super.init(t,e,W)}static getInstance(t){return t.M_Tabs}destroy(){this._removeEventHandlers(),this._indicator.parentNode.removeChild(this._indicator),this.options.swipeable?this._teardownSwipeableTabs():this._teardownNormalTabs(),this.el.M_Tabs=void 0}get index(){return this._index}_setupEventHandlers(){window.addEventListener("resize",this._handleWindowResize),this.el.addEventListener("click",this._handleTabClick),this.el.addEventListener("wheel",t=>{0!==t.deltaY&&(t.preventDefault(),this.el.scrollLeft+=1*t.deltaY)})}_removeEventHandlers(){window.removeEventListener("resize",this._handleWindowResize),this.el.removeEventListener("click",this._handleTabClick)}_handleWindowResize=()=>{this._setTabsAndTabWidth(),0!==this._tabWidth&&0!==this._tabsWidth&&(this._indicator.style.left=this._calcLeftPos(this._activeTabLink)+"px",this._indicator.style.right=this._calcRightPos(this._activeTabLink)+"px")};_handleTabClick=t=>{let e=t.target;if(!e)return;let i=e.parentElement;for(;i&&!i.classList.contains("tab");)e=e.parentElement,i=i.parentElement;if(!e||!i.classList.contains("tab"))return;if(i.classList.contains("disabled"))return void t.preventDefault();if(e.hasAttribute("target"))return;this._activeTabLink.classList.remove("active");const s=this._content;this._activeTabLink=e,e.hash&&(this._content=document.querySelector(e.hash)),this._tabLinks=this.el.querySelectorAll("li.tab > a"),this._activeTabLink.classList.add("active");const n=this._index;this._index=Math.max(Array.from(this._tabLinks).indexOf(e),0),this.options.swipeable?this._tabsCarousel&&this._tabsCarousel.set(this._index,()=>{"function"==typeof this.options.onShow&&this.options.onShow.call(this,this._content)}):this._content&&(this._content.style.display="block",this._content.classList.add("active"),"function"==typeof this.options.onShow&&this.options.onShow.call(this,this._content),s&&s!==this._content&&(s.style.display="none",s.classList.remove("active"))),this._setTabsAndTabWidth(),this._animateIndicator(n),t.preventDefault()};_createIndicator(){const t=document.createElement("li");t.classList.add("indicator"),this.el.appendChild(t),this._indicator=t,this._indicator.style.left=this._calcLeftPos(this._activeTabLink)+"px",this._indicator.style.right=this._calcRightPos(this._activeTabLink)+"px"}_setupActiveTabLink(){if(this._activeTabLink=Array.from(this._tabLinks).find(t=>t.getAttribute("href")===location.hash),!this._activeTabLink){let t=this.el.querySelector("li.tab a.active");t||(t=this.el.querySelector("li.tab a")),this._activeTabLink=t}Array.from(this._tabLinks).forEach(t=>t.classList.remove("active")),this._activeTabLink.classList.add("active"),this._index=Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink),0),this._activeTabLink&&this._activeTabLink.hash&&(this._content=document.querySelector(this._activeTabLink.hash),this._content&&this._content.classList.add("active"))}_setupSwipeableTabs(){window.innerWidth>this.options.responsiveThreshold&&(this.options.swipeable=!1);const t=[];this._tabLinks.forEach(e=>{if(e.hash){const i=document.querySelector(e.hash);i.classList.add("carousel-item"),t.push(i)}});const e=document.createElement("div");e.classList.add("tabs-content","carousel","carousel-slider"),t[0].parentElement.insertBefore(e,t[0]),t.forEach(t=>{e.appendChild(t),t.style.display=""});const i=this._activeTabLink.parentElement,s=Array.from(i.parentNode.children).indexOf(i);this._tabsCarousel=p.init(e,{fullWidth:!0,noWrap:!0,onCycleTo:t=>{const e=this._index;this._index=Array.from(t.parentNode.children).indexOf(t),this._activeTabLink.classList.remove("active"),this._activeTabLink=Array.from(this._tabLinks)[this._index],this._activeTabLink.classList.add("active"),this._animateIndicator(e),"function"==typeof this.options.onShow&&this.options.onShow.call(this,this._content)}}),this._tabsCarousel.set(s)}_teardownSwipeableTabs(){const t=this._tabsCarousel.el;this._tabsCarousel.destroy(),t.append(t.parentElement),t.remove()}_setupNormalTabs(){Array.from(this._tabLinks).forEach(t=>{if(t!==this._activeTabLink&&t.hash){const e=document.querySelector(t.hash);e&&(e.style.display="none")}})}_teardownNormalTabs(){this._tabLinks.forEach(t=>{if(t.hash){const e=document.querySelector(t.hash);e&&(e.style.display="")}})}_setTabsAndTabWidth(){this._tabsWidth=this.el.getBoundingClientRect().width,this._tabWidth=Math.max(this._tabsWidth,this.el.scrollWidth)/this._tabLinks.length}_calcRightPos(t){return Math.ceil(this._tabsWidth-t.offsetLeft-t.getBoundingClientRect().width)}_calcLeftPos(t){return Math.floor(t.offsetLeft)}updateTabIndicator(){this._setTabsAndTabWidth(),this._animateIndicator(this._index)}_animateIndicator(t){let e=0,i=0;this._index-t>=0?e=90:i=90,this._indicator.style.transition=`\n left ${this.options.duration}ms ease-out ${e}ms,\n right ${this.options.duration}ms ease-out ${i}ms`,this._indicator.style.left=this._calcLeftPos(this._activeTabLink)+"px",this._indicator.style.right=this._calcRightPos(this._activeTabLink)+"px"}select(t){const e=Array.from(this._tabLinks).find(e=>e.getAttribute("href")==="#"+t);e&&e.click()}}const B={dialRadius:135,outerRadius:105,innerRadius:70,tickRadius:20,duration:350,container:null,defaultTime:"now",fromNow:0,showClearBtn:!1,autoSubmit:!0,i18n:{cancel:"Cancel",clear:"Clear",done:"Ok"},twelveHour:!0,vibrate:!0,onSelect:null,onInputInteraction:null,onDone:null,onCancel:null,displayPlugin:null,displayPluginOptions:null};class q extends i{id;containerEl;plate;digitalClock;inputHours;inputMinutes;x0;y0;moved;dx;dy;currentView;hand;minutesView;hours;minutes;time;amOrPm;static _template;vibrate;_canvas;hoursView;spanAmPm;footer;_amBtn;_pmBtn;bg;bearing;g;toggleViewTimer;vibrateTimer;displayPlugin;constructor(t,i){super(t,i,q),this.el.M_Timepicker=this,this.options={...q.defaults,...i},this.id=e.guid(),this._insertHTMLIntoDOM(),this._setupVariables(),this._setupEventHandlers(),this._clockSetup(),this.options.displayPlugin&&this._setupDisplayPlugin(),this._pickerSetup()}static get defaults(){return B}static init(t,e={}){return super.init(t,e,q)}static _addLeadingZero(t){return(t<10?"0":"")+t}static _createSVGEl(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}static _Pos(t){return t.type.startsWith("touch")&&t.targetTouches.length>=1?{x:t.targetTouches[0].clientX,y:t.targetTouches[0].clientY}:{x:t.clientX,y:t.clientY}}static getInstance(t){return t.M_Timepicker}destroy(){this._removeEventHandlers(),this.containerEl.remove(),this.el.M_Timepicker=void 0}_setupEventHandlers(){this.el.addEventListener("click",this._handleInputClick),this.el.addEventListener("keydown",this._handleInputKeydown),this.plate.addEventListener("mousedown",this._handleClockClickStart),this.plate.addEventListener("touchstart",this._handleClockClickStart),this.digitalClock.addEventListener("keyup",this._inputFromTextField),this.inputHours.addEventListener("focus",()=>this.showView("hours")),this.inputHours.addEventListener("focusout",()=>this.formatHours()),this.inputMinutes.addEventListener("focus",()=>this.showView("minutes")),this.inputMinutes.addEventListener("focusout",()=>this.formatMinutes())}_removeEventHandlers(){this.el.removeEventListener("click",this._handleInputClick),this.el.removeEventListener("keydown",this._handleInputKeydown)}_handleInputClick=()=>{this.inputHours.focus(),"function"==typeof this.options.onInputInteraction&&this.options.onInputInteraction.call(this),this.displayPlugin&&this.displayPlugin.show()};_handleInputKeydown=t=>{e.keys.ENTER.includes(t.key)&&(t.preventDefault(),this.inputHours.focus(),"function"==typeof this.options.onInputInteraction&&this.options.onInputInteraction.call(this),this.displayPlugin&&this.displayPlugin.show())};_handleTimeInputEnterKey=t=>{e.keys.ENTER.includes(t.key)&&(t.preventDefault(),this._inputFromTextField())};_handleClockClickStart=t=>{t.preventDefault();const e=this.plate.getBoundingClientRect(),i=e.left,s=e.top;this.x0=i+this.options.dialRadius,this.y0=s+this.options.dialRadius,this.moved=!1;const n=q._Pos(t);this.dx=n.x-this.x0,this.dy=n.y-this.y0,this.setHand(this.dx,this.dy,!1),document.addEventListener("mousemove",this._handleDocumentClickMove),document.addEventListener("touchmove",this._handleDocumentClickMove),document.addEventListener("mouseup",this._handleDocumentClickEnd),document.addEventListener("touchend",this._handleDocumentClickEnd)};_handleDocumentClickMove=t=>{t.preventDefault();const e=q._Pos(t),i=e.x-this.x0,s=e.y-this.y0;this.moved=!0,this.setHand(i,s,!1)};_handleDocumentClickEnd=t=>{t.preventDefault(),document.removeEventListener("mouseup",this._handleDocumentClickEnd),document.removeEventListener("touchend",this._handleDocumentClickEnd);const e=q._Pos(t),i=e.x-this.x0,s=e.y-this.y0;this.moved&&i===this.dx&&s===this.dy&&this.setHand(i,s),"hours"===this.currentView?(this.inputMinutes.focus(),this.showView("minutes",this.options.duration/2)):setTimeout(()=>{this.options.autoSubmit&&this.done()},this.options.duration/2),"function"==typeof this.options.onSelect&&this.options.onSelect.call(this,this.hours,this.minutes),document.removeEventListener("mousemove",this._handleDocumentClickMove),document.removeEventListener("touchmove",this._handleDocumentClickMove)};_insertHTMLIntoDOM(){const t=document.createElement("template");t.innerHTML=q._template.trim(),this.containerEl=t.content.firstChild,this.containerEl.id="container-"+this.id;const e=this.options.container,i=e instanceof HTMLElement?e:document.querySelector(e);this.options.container&&i?i.append(this.containerEl):this.el.parentElement.appendChild(this.containerEl)}_setupVariables(){this.currentView="hours",this.vibrate=navigator.vibrate?"vibrate":navigator.webkitVibrate?"webkitVibrate":null,this._canvas=this.containerEl.querySelector(".timepicker-canvas"),this.plate=this.containerEl.querySelector(".timepicker-plate"),this.digitalClock=this.containerEl.querySelector(".timepicker-display-column"),this.hoursView=this.containerEl.querySelector(".timepicker-hours"),this.minutesView=this.containerEl.querySelector(".timepicker-minutes"),this.inputHours=this.containerEl.querySelector(".timepicker-input-hours"),this.inputMinutes=this.containerEl.querySelector(".timepicker-input-minutes"),this.spanAmPm=this.containerEl.querySelector(".timepicker-span-am-pm"),this.footer=this.containerEl.querySelector(".timepicker-footer"),this.amOrPm="PM"}_pickerSetup(){this.options.showClearBtn&&e.createButton(this.footer,this.options.i18n.clear,["timepicker-clear"],!0,this.clear),this.options.autoSubmit||e.createConfirmationContainer(this.footer,this.options.i18n.done,this.options.i18n.cancel,this.confirm,this.cancel),this._updateTimeFromInput(),this.showView("hours")}_setupDisplayPlugin(){"docked"===this.options.displayPlugin&&(this.displayPlugin=b.init(this.el,this.containerEl,this.options.displayPluginOptions)),"modal"===this.options.displayPlugin&&(this.displayPlugin=C.init(this.el,this.containerEl,{...this.options.displayPluginOptions,classList:["timepicker-modal"]}),this.footer.remove(),this.footer=this.displayPlugin.footer)}_clockSetup(){this.options.twelveHour&&(this._amBtn=document.createElement("div"),this._amBtn.classList.add("am-btn","btn"),this._amBtn.innerText="AM",this._amBtn.tabIndex=0,this._amBtn.addEventListener("click",this._handleAmPmClick),this._amBtn.addEventListener("keypress",this._handleAmPmKeypress),this.spanAmPm.appendChild(this._amBtn),this._pmBtn=document.createElement("div"),this._pmBtn.classList.add("pm-btn","btn"),this._pmBtn.innerText="PM",this._pmBtn.tabIndex=0,this._pmBtn.addEventListener("click",this._handleAmPmClick),this._pmBtn.addEventListener("keypress",this._handleAmPmKeypress),this.spanAmPm.appendChild(this._pmBtn)),this._buildHoursView(),this._buildMinutesView(),this._buildSVGClock()}_buildSVGClock(){const t=this.options.dialRadius,e=this.options.tickRadius,i=2*t,s=q._createSVGEl("svg");s.setAttribute("class","timepicker-svg"),s.setAttribute("width",i.toString()),s.setAttribute("height",i.toString());const n=q._createSVGEl("g");n.setAttribute("transform","translate("+t+","+t+")");const o=q._createSVGEl("circle");o.setAttribute("class","timepicker-canvas-bearing"),o.setAttribute("cx","0"),o.setAttribute("cy","0"),o.setAttribute("r","4");const a=q._createSVGEl("line");a.setAttribute("x1","0"),a.setAttribute("y1","0");const l=q._createSVGEl("circle");l.setAttribute("class","timepicker-canvas-bg"),l.setAttribute("r",e.toString()),n.appendChild(a),n.appendChild(l),n.appendChild(o),s.appendChild(n),this._canvas.appendChild(s),this.hand=a,this.bg=l,this.bearing=o,this.g=n}_buildHoursView(){if(this.options.twelveHour)for(let t=1;t<13;t+=1){const e=t/6*Math.PI,i=this.options.outerRadius;this._buildHoursTick(t,e,i)}else for(let t=0;t<24;t+=1){const e=t/6*Math.PI,i=t>0&&t<13?this.options.innerRadius:this.options.outerRadius;this._buildHoursTick(t,e,i)}}_buildHoursTick(t,e,i){const s=document.createElement("div");s.classList.add("timepicker-tick"),s.style.left=this.options.dialRadius+Math.sin(e)*i-this.options.tickRadius+"px",s.style.top=this.options.dialRadius-Math.cos(e)*i-this.options.tickRadius+"px",s.innerHTML=0===t?"00":t.toString(),this.hoursView.appendChild(s)}_buildMinutesView(){const t=document.createElement("div");t.classList.add("timepicker-tick");for(let e=0;e<60;e+=5){const i=t.cloneNode(!0),s=e/30*Math.PI;i.style.left=this.options.dialRadius+Math.sin(s)*this.options.outerRadius-this.options.tickRadius+"px",i.style.top=this.options.dialRadius-Math.cos(s)*this.options.outerRadius-this.options.tickRadius+"px",i.innerHTML=q._addLeadingZero(e),this.minutesView.appendChild(i)}}_handleAmPmClick=t=>{this._handleAmPmInteraction(t.target)};_handleAmPmKeypress=t=>{e.keys.ENTER.includes(t.key)&&this._handleAmPmInteraction(t.target)};_handleAmPmInteraction=t=>{this.amOrPm=t.classList.contains("am-btn")?"AM":"PM",this._updateAmPmView()};_updateAmPmView(){this.options.twelveHour&&("PM"===this.amOrPm?(this._amBtn.classList.remove("filled"),this._pmBtn.classList.add("filled")):"AM"===this.amOrPm&&(this._amBtn.classList.add("filled"),this._pmBtn.classList.remove("filled")))}_updateTimeFromInput(){let t=((this.el.value||this.options.defaultTime||"")+"").split(":");if(this.options.twelveHour&&void 0!==t[1]&&(t[1].toUpperCase().indexOf("AM")>0?this.amOrPm="AM":this.amOrPm="PM",t[1]=t[1].replace("AM","").replace("PM","")),"now"===t[0]){const e=new Date(+new Date+this.options.fromNow);t=[e.getHours().toString(),e.getMinutes().toString()],this.options.twelveHour&&(this.amOrPm=parseInt(t[0])>=12&&parseInt(t[0])<24?"PM":"AM")}this.hours=+t[0]||0,this.minutes=+t[1]||0,this.inputHours.value=q._addLeadingZero(this.hours),this.inputMinutes.value=q._addLeadingZero(this.minutes),this._updateAmPmView()}showView=(t,e=null)=>{"minutes"===t&&getComputedStyle(this.hoursView).visibility;const i="hours"===t,s=i?this.hoursView:this.minutesView,n=i?this.minutesView:this.hoursView;this.currentView=t,n.classList.add("timepicker-dial-out"),s.style.visibility="visible",s.classList.remove("timepicker-dial-out"),this.resetClock(e),clearTimeout(this.toggleViewTimer),this.toggleViewTimer=setTimeout(()=>{n.style.visibility="hidden"},this.options.duration)};resetClock(t){const e=this.currentView,i=this[e],s="hours"===e,n=i*(Math.PI/(s?6:30)),o=s&&i>0&&i<13?this.options.innerRadius:this.options.outerRadius,a=Math.sin(n)*o,l=-Math.cos(n)*o;t?(this._canvas?.classList.add("timepicker-canvas-out"),setTimeout(()=>{this._canvas?.classList.remove("timepicker-canvas-out"),this.setHand(a,l)},t)):this.setHand(a,l)}_inputFromTextField=()=>{const t="hours"===this.currentView;if(t&&""!==this.inputHours.value){const e=parseInt(this.inputHours.value);e>0&&e<(this.options.twelveHour?13:24)?this.hours=e:this.setHoursDefault(),this.drawClockFromTimeInput(this.hours,t)}else if(!t&&""!==this.inputMinutes.value){const e=parseInt(this.inputMinutes.value);e>=0&&e<60?this.minutes=e:(this.minutes=(new Date).getMinutes(),this.inputMinutes.value=this.minutes.toString()),this.drawClockFromTimeInput(this.minutes,t)}};drawClockFromTimeInput(t,e){const i=t*(Math.PI/(e?6:30));let s;s=this.options.twelveHour?this.options.outerRadius:e&&t>0&&t<13?this.options.innerRadius:this.options.outerRadius,this.setClockAttributes(i,s)}setHand(t,e,i=!1){const s="hours"===this.currentView,n=Math.PI/(s||i?6:30),o=Math.sqrt(t*t+e*e),a=s&&o<(this.options.outerRadius+this.options.innerRadius)/2;let l=Math.atan2(t,-e),r=a?this.options.innerRadius:this.options.outerRadius;this.options.twelveHour&&(r=this.options.outerRadius),l<0&&(l=2*Math.PI+l);let h=Math.round(l/n);l=h*n,this.options.twelveHour?s?0===h&&(h=12):(i&&(h*=5),60===h&&(h=0)):s?(12===h&&(h=0),h=a?0===h?12:h:0===h?0:h+12):(i&&(h*=5),60===h&&(h=0)),this[this.currentView]!==h&&this.vibrate&&this.options.vibrate&&(this.vibrateTimer||(navigator[this.vibrate](10),this.vibrateTimer=setTimeout(()=>{this.vibrateTimer=null},100))),this[this.currentView]=h,s?this.inputHours.value=q._addLeadingZero(h):this.inputMinutes.value=q._addLeadingZero(h),this.setClockAttributes(l,r)}setClockAttributes(t,e){const i=Math.sin(t)*(e-this.options.tickRadius),s=-Math.cos(t)*(e-this.options.tickRadius),n=Math.sin(t)*e,o=-Math.cos(t)*e;this.hand.setAttribute("x2",i.toString()),this.hand.setAttribute("y2",s.toString()),this.bg.setAttribute("cx",n.toString()),this.bg.setAttribute("cy",o.toString())}formatHours(){""==this.inputHours.value&&this.setHoursDefault(),this.inputHours.value=q._addLeadingZero(Number(this.inputHours.value))}formatMinutes(){""==this.inputMinutes.value&&(this.minutes=(new Date).getMinutes()),this.inputMinutes.value=q._addLeadingZero(Number(this.inputMinutes.value))}setHoursDefault(){this.hours=(new Date).getHours(),this.inputHours.value=(this.hours%(this.options.twelveHour?12:24)).toString()}done=(t=null)=>{const e=this.el.value;let i=t?"":q._addLeadingZero(this.hours)+":"+q._addLeadingZero(this.minutes);this.time=i,!t&&this.options.twelveHour&&(i=`${i} ${this.amOrPm}`),this.el.value=i,i!==e&&this.el.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0,composed:!0}))};confirm=()=>{this.done(),this.displayPlugin&&this.displayPlugin.hide(),"function"==typeof this.options.onDone&&this.options.onDone.call(this)};cancel=()=>{this.displayPlugin&&this.displayPlugin.hide(),"function"==typeof this.options.onCancel&&this.options.onCancel.call(this)};clear=()=>{this.done(!0)};open(){return console.warn("Timepicker.close() is deprecated. Remove this method and wrap in modal yourself."),this}close(){return console.warn("Timepicker.close() is deprecated. Remove this method and wrap in modal yourself."),this}static{q._template='
\n
\n
\n
\n
\n \n
\n
\n :\n
\n
\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n
\n
'}}const F={text:"",displayLength:4e3,inDuration:300,outDuration:375,classes:"",completeCallback:null,activationPercent:.8};class V{el;timeRemaining;panning;options;message;counterInterval;wasSwiped;startingXPos;xPos;time;deltaX;velocityX;static _toasts;static _container;static _draggedToast;constructor(t){this.options={...V.defaults,...t},this.message=this.options.text,this.panning=!1,this.timeRemaining=this.options.displayLength,0===V._toasts.length&&V._createContainer(),V._toasts.push(this);const e=this._createToast();e.M_Toast=this,this.el=e,this._animateIn(),this._setTimer()}static get defaults(){return F}static getInstance(t){return t.M_Toast}static _createContainer(){const t=document.createElement("div");t.setAttribute("id","toast-container"),t.addEventListener("touchstart",V._onDragStart),t.addEventListener("touchmove",V._onDragMove),t.addEventListener("touchend",V._onDragEnd),t.addEventListener("mousedown",V._onDragStart),document.addEventListener("mousemove",V._onDragMove),document.addEventListener("mouseup",V._onDragEnd),document.body.appendChild(t),V._container=t}static _removeContainer(){document.removeEventListener("mousemove",V._onDragMove),document.removeEventListener("mouseup",V._onDragEnd),V._container&&(V._container.remove(),V._container=null)}static _onDragStart(t){if(t.target&&t.target.closest(".toast")){const e=t.target.closest(".toast").M_Toast;e.panning=!0,V._draggedToast=e,e.el.classList.add("panning"),e.el.style.transition="",e.startingXPos=V._xPos(t),e.time=Date.now(),e.xPos=V._xPos(t)}}static _onDragMove(t){if(V._draggedToast){t.preventDefault();const e=V._draggedToast;e.deltaX=Math.abs(e.xPos-V._xPos(t)),e.xPos=V._xPos(t),e.velocityX=e.deltaX/(Date.now()-e.time),e.time=Date.now();const i=e.xPos-e.startingXPos,s=e.el.offsetWidth*e.options.activationPercent;e.el.style.transform=`translateX(${i}px)`,e.el.style.opacity=(1-Math.abs(i/s)).toString()}}static _onDragEnd(){if(V._draggedToast){const t=V._draggedToast;t.panning=!1,t.el.classList.remove("panning");const e=t.xPos-t.startingXPos,i=t.el.offsetWidth*t.options.activationPercent;Math.abs(e)>i||t.velocityX>1?(t.wasSwiped=!0,t.dismiss()):(t.el.style.transition="transform .2s, opacity .2s",t.el.style.transform="",t.el.style.opacity=""),V._draggedToast=null}}static _xPos(t){return t.type.startsWith("touch")&&t.targetTouches.length>=1?t.targetTouches[0].clientX:t.clientX}static dismissAll(){for(const t in V._toasts)V._toasts[t].dismiss()}_createToast(){let t=this.options.toastId?document.getElementById(this.options.toastId):document.createElement("div");if(t instanceof HTMLTemplateElement){const e=t.content.cloneNode(!0);t=e.firstElementChild}return t.classList.add("toast"),t.setAttribute("role","alert"),t.setAttribute("aria-live","assertive"),t.setAttribute("aria-atomic","true"),this.options.classes.length>0&&t.classList.add(...this.options.classes.split(" ")),this.message&&(t.innerText=this.message),V._container&&V._container.appendChild(t),t}_animateIn(){this.el.style.display="",this.el.style.opacity="0",this.el.style.transition=`\n top ${this.options.inDuration}ms ease,\n opacity ${this.options.inDuration}ms ease\n `,setTimeout(()=>{this.el.style.top="0",this.el.style.opacity="1"},1)}_setTimer(){this.timeRemaining!==1/0&&(this.counterInterval=setInterval(()=>{this.panning||(this.timeRemaining-=20),this.timeRemaining<=0&&this.dismiss()},20))}dismiss(){clearInterval(this.counterInterval);const t=this.el.offsetWidth*this.options.activationPercent;this.wasSwiped&&(this.el.style.transition="transform .05s, opacity .05s",this.el.style.transform=`translateX(${t}px)`,this.el.style.opacity="0"),this.el.style.transition=`\n margin ${this.options.outDuration}ms ease,\n opacity ${this.options.outDuration}ms ease`,setTimeout(()=>{this.el.style.opacity="0",this.el.style.marginTop="-40px"},1),setTimeout(()=>{"function"==typeof this.options.completeCallback&&this.options.completeCallback(),this.el.id!=this.options.toastId&&(this.el.remove(),V._toasts.splice(V._toasts.indexOf(this),1),0===V._toasts.length&&V._removeContainer())},this.options.outDuration)}static{V._toasts=[],V._container=null,V._draggedToast=null}}const $={exitDelay:200,enterDelay:0,text:"",margin:5,inDuration:250,outDuration:200,position:"bottom",transitionMovement:10,opacity:1};class N extends i{isOpen;isHovered;isFocused;tooltipEl;_exitDelayTimeout;_enterDelayTimeout;xMovement;yMovement;constructor(t,e){super(t,e,N),this.el.M_Tooltip=this,this.options={...N.defaults,...this._getAttributeOptions(),...e},this.isOpen=!1,this.isHovered=!1,this.isFocused=!1,this._appendTooltipEl(),this._setupEventHandlers()}static get defaults(){return $}static init(t,e={}){return super.init(t,e,N)}static getInstance(t){return t.M_Tooltip}destroy(){this.tooltipEl.remove(),this._removeEventHandlers(),this.el.M_Tooltip=void 0}_appendTooltipEl(){this.tooltipEl=document.createElement("div"),this.tooltipEl.classList.add("material-tooltip");const t=this.options.tooltipId?document.getElementById(this.options.tooltipId):document.createElement("div");this.tooltipEl.append(t),t.style.display="",t.classList.add("tooltip-content"),this._setTooltipContent(t),this.tooltipEl.appendChild(t),document.body.appendChild(this.tooltipEl)}_setTooltipContent(t){this.options.tooltipId||(t.innerText=this.options.text)}_updateTooltipContent(){this._setTooltipContent(this.tooltipEl.querySelector(".tooltip-content"))}_setupEventHandlers(){this.el.addEventListener("mouseenter",this._handleMouseEnter),this.el.addEventListener("mouseleave",this._handleMouseLeave),this.el.addEventListener("focus",this._handleFocus,!0),this.el.addEventListener("blur",this._handleBlur,!0)}_removeEventHandlers(){this.el.removeEventListener("mouseenter",this._handleMouseEnter),this.el.removeEventListener("mouseleave",this._handleMouseLeave),this.el.removeEventListener("focus",this._handleFocus,!0),this.el.removeEventListener("blur",this._handleBlur,!0)}open=t=>{this.isOpen||(t=void 0===t||void 0,this.isOpen=!0,this.options={...this.options,...this._getAttributeOptions()},this._updateTooltipContent(),this._setEnterDelayTimeout(t))};close=()=>{this.isOpen&&(this.isHovered=!1,this.isFocused=!1,this.isOpen=!1,this._setExitDelayTimeout())};_setExitDelayTimeout(){clearTimeout(this._exitDelayTimeout),this._exitDelayTimeout=setTimeout(()=>{this.isHovered||this.isFocused||this._animateOut()},this.options.exitDelay)}_setEnterDelayTimeout(t){clearTimeout(this._enterDelayTimeout),this._enterDelayTimeout=setTimeout(()=>{(this.isHovered||this.isFocused||t)&&this._animateIn()},this.options.enterDelay)}_positionTooltip(){const t=this.tooltipEl,i=this.el,s=i.offsetHeight,n=i.offsetWidth,o=t.offsetHeight,a=t.offsetWidth,l=this.options.margin;this.xMovement=0,this.yMovement=0;let r=i.getBoundingClientRect().top+e.getDocumentScrollTop(),h=i.getBoundingClientRect().left+e.getDocumentScrollLeft();"top"===this.options.position?(r+=-o-l,h+=n/2-a/2,this.yMovement=-this.options.transitionMovement):"right"===this.options.position?(r+=s/2-o/2,h+=n+l,this.xMovement=this.options.transitionMovement):"left"===this.options.position?(r+=s/2-o/2,h+=-a-l,this.xMovement=-this.options.transitionMovement):(r+=s+l,h+=n/2-a/2,this.yMovement=this.options.transitionMovement);const d=this._repositionWithinScreen(h,r,a,o);t.style.top=d.y+"px",t.style.left=d.x+"px"}_repositionWithinScreen(t,i,s,n){const o=e.getDocumentScrollLeft(),a=e.getDocumentScrollTop();let l=t-o,r=i-a;const h={left:l,top:r,width:s,height:n},d=this.options.margin+this.options.transitionMovement,c=e.checkWithinContainer(document.body,h,d);return c.left?l=d:c.right&&(l-=l+s-window.innerWidth),c.top?r=d:c.bottom&&(r-=r+n-window.innerHeight),{x:l+o,y:r+a}}_animateIn(){this._positionTooltip(),this.tooltipEl.style.visibility="visible";const t=this.options.inDuration;this.tooltipEl.style.transition=`\n transform ${t}ms ease-out,\n opacity ${t}ms ease-out`,setTimeout(()=>{this.tooltipEl.style.transform=`translateX(${this.xMovement}px) translateY(${this.yMovement}px)`,this.tooltipEl.style.opacity=(this.options.opacity||1).toString()},1)}_animateOut(){const t=this.options.outDuration;this.tooltipEl.style.transition=`\n transform ${t}ms ease-out,\n opacity ${t}ms ease-out`,setTimeout(()=>{this.tooltipEl.style.transform="translateX(0px) translateY(0px)",this.tooltipEl.style.opacity="0"},1)}_handleMouseEnter=()=>{this.isHovered=!0,this.isFocused=!1,this.open(!1)};_handleMouseLeave=()=>{this.isHovered=!1,this.isFocused=!1,this.close()};_handleFocus=()=>{e.tabPressed&&(this.isFocused=!0,this.open(!1))};_handleBlur=()=>{this.isFocused=!1,this.close()};_getAttributeOptions(){const t={},e=this.el.getAttribute("data-tooltip"),i=this.el.getAttribute("data-tooltip-id"),s=this.el.getAttribute("data-position");return e&&(t.text=e),s&&(t.position=s),i&&(t.tooltipId=i),t}}const z={};class X extends i{_mousedown;value;thumb;constructor(t,e){super(t,e,X),this.el.M_Range=this,this.options={...X.defaults,...e},this._mousedown=!1,this._setupThumb(),this._setupEventHandlers()}static get defaults(){return z}static init(t,e={}){return super.init(t,e,X)}static getInstance(t){return t.M_Range}destroy(){this._removeEventHandlers(),this._removeThumb(),this.el.M_Range=void 0}_setupEventHandlers(){this.el.addEventListener("change",this._handleRangeChange),this.el.addEventListener("mousedown",this._handleRangeMousedownTouchstart),this.el.addEventListener("touchstart",this._handleRangeMousedownTouchstart),this.el.addEventListener("input",this._handleRangeInputMousemoveTouchmove),this.el.addEventListener("mousemove",this._handleRangeInputMousemoveTouchmove),this.el.addEventListener("touchmove",this._handleRangeInputMousemoveTouchmove),this.el.addEventListener("mouseup",this._handleRangeMouseupTouchend),this.el.addEventListener("touchend",this._handleRangeMouseupTouchend),this.el.addEventListener("blur",this._handleRangeBlurMouseoutTouchleave),this.el.addEventListener("mouseout",this._handleRangeBlurMouseoutTouchleave),this.el.addEventListener("touchleave",this._handleRangeBlurMouseoutTouchleave)}_removeEventHandlers(){this.el.removeEventListener("change",this._handleRangeChange),this.el.removeEventListener("mousedown",this._handleRangeMousedownTouchstart),this.el.removeEventListener("touchstart",this._handleRangeMousedownTouchstart),this.el.removeEventListener("input",this._handleRangeInputMousemoveTouchmove),this.el.removeEventListener("mousemove",this._handleRangeInputMousemoveTouchmove),this.el.removeEventListener("touchmove",this._handleRangeInputMousemoveTouchmove),this.el.removeEventListener("mouseup",this._handleRangeMouseupTouchend),this.el.removeEventListener("touchend",this._handleRangeMouseupTouchend),this.el.removeEventListener("blur",this._handleRangeBlurMouseoutTouchleave),this.el.removeEventListener("mouseout",this._handleRangeBlurMouseoutTouchleave),this.el.removeEventListener("touchleave",this._handleRangeBlurMouseoutTouchleave)}_handleRangeChange=()=>{this.value.innerHTML=this.el.value,this.thumb.classList.contains("active")||this._showRangeBubble();const t=this._calcRangeOffset();this.thumb.classList.add("active"),this.thumb.style.left=t+"px"};_handleRangeMousedownTouchstart=t=>{if(this.value.innerHTML=this.el.value,this._mousedown=!0,this.el.classList.add("active"),this.thumb.classList.contains("active")||this._showRangeBubble(),"input"!==t.type){const t=this._calcRangeOffset();this.thumb.classList.add("active"),this.thumb.style.left=t+"px"}};_handleRangeInputMousemoveTouchmove=()=>{if(this._mousedown){this.thumb.classList.contains("active")||this._showRangeBubble();const t=this._calcRangeOffset();this.thumb.classList.add("active"),this.thumb.style.left=t+"px",this.value.innerHTML=this.el.value}};_handleRangeMouseupTouchend=()=>{this._mousedown=!1,this.el.classList.remove("active")};_handleRangeBlurMouseoutTouchleave=()=>{if(!this._mousedown){const t=7+parseInt(getComputedStyle(this.el).paddingLeft)+"px";if(this.thumb.classList.contains("active")){const e=100;this.thumb.style.transition="none",setTimeout(()=>{this.thumb.style.transition=`\n height ${e}ms ease,\n width ${e}ms ease,\n top ${e}ms ease,\n margin ${e}ms ease\n `,this.thumb.style.height="0",this.thumb.style.width="0",this.thumb.style.top="0",this.thumb.style.marginLeft=t},1)}this.thumb.classList.remove("active")}};_setupThumb(){this.thumb=document.createElement("span"),this.value=document.createElement("span"),this.thumb.classList.add("thumb"),this.value.classList.add("value"),this.thumb.append(this.value),this.el.after(this.thumb)}_removeThumb(){this.thumb.remove()}_showRangeBubble(){const t=-7+parseInt(getComputedStyle(this.thumb.parentElement).paddingLeft)+"px";this.thumb.style.transition="\n height 300ms ease,\n width 300ms ease,\n top 300ms ease,\n margin 300ms ease\n ",this.thumb.style.height="30px",this.thumb.style.width="30px",this.thumb.style.top="-30px",this.thumb.style.marginLeft=t}_calcRangeOffset(){const t=this.el.getBoundingClientRect().width-15,e=parseFloat(this.el.getAttribute("max"))||100,i=parseFloat(this.el.getAttribute("min"))||0;return(parseFloat(this.el.value)-i)/(e-i)*t}static Init(){"undefined"!=typeof document&&X.init(document?.querySelectorAll("input[type=range]"),{})}}const K={onOpen:null,onClose:null};class Y extends i{isOpen;static _taptargets;wrapper;originEl;waveEl;contentEl;constructor(t,e){super(t,e,Y),this.el.M_TapTarget=this,this.options={...Y.defaults,...e},this.isOpen=!1,this.originEl=document.querySelector(`#${t.dataset.target}`),this.originEl.tabIndex=0,this._setup(),this._calculatePositioning(),this._setupEventHandlers(),Y._taptargets.push(this)}static get defaults(){return K}static init(t,e={}){return super.init(t,e,Y)}static getInstance(t){return t.M_TapTarget}destroy(){this._removeEventHandlers(),this.el.M_TapTarget=void 0;const t=Y._taptargets.indexOf(this);t>=0&&Y._taptargets.splice(t,1)}_setupEventHandlers(){this.originEl.addEventListener("click",this._handleTargetToggle),this.originEl.addEventListener("keypress",this._handleKeyboardInteraction,!0),window.addEventListener("resize",this._handleThrottledResize)}_removeEventHandlers(){this.originEl.removeEventListener("click",this._handleTargetToggle),this.originEl.removeEventListener("keypress",this._handleKeyboardInteraction,!0),window.removeEventListener("resize",this._handleThrottledResize)}_handleThrottledResize=()=>e.throttle(this._handleResize,200).bind(this);_handleKeyboardInteraction=t=>{e.keys.ENTER.includes(t.key)&&this._handleTargetToggle()};_handleTargetToggle=()=>{this.isOpen?this.close():this.open()};_handleResize=()=>{this._calculatePositioning()};_handleDocumentClick=t=>{t.target.closest(`#${this.el.dataset.target}`)===this.originEl||t.target.closest(".tap-target-wrapper")||this.close()};_setup(){this.wrapper=this.el.parentElement,this.waveEl=this.wrapper.querySelector(".tap-target-wave"),this.el.parentElement.ariaExpanded="false",this.originEl.style.zIndex="1002",this.contentEl=this.el.querySelector(".tap-target-content"),this.wrapper.classList.contains(".tap-target-wrapper")||(this.wrapper=document.createElement("div"),this.wrapper.classList.add("tap-target-wrapper"),this.el.before(this.wrapper),this.wrapper.append(this.el)),this.contentEl||(this.contentEl=document.createElement("div"),this.contentEl.classList.add("tap-target-content"),this.el.append(this.contentEl)),this.waveEl||(this.waveEl=document.createElement("div"),this.waveEl.classList.add("tap-target-wave"),this.wrapper.append(this.waveEl))}_offset(t){const e=t.getBoundingClientRect(),i=document.documentElement;return{top:e.top+window.pageYOffset-i.clientTop,left:e.left+window.pageXOffset-i.clientLeft}}_calculatePositioning(){let t="fixed"===getComputedStyle(this.originEl).position;if(!t){let e=this.originEl;const i=[];for(;(e=e.parentNode)&&e!==document;)i.push(e);for(let e=0;eh,u=n<=d,m=n>d,v=o>=.25*a&&o<=.75*a,g=this.el.offsetWidth,_=this.el.offsetHeight,y=n+s/2-_/2,f=o+i/2-g/2,E=t?"fixed":"absolute",w=v?g:g/2+i,b=_/2,L=u?_/2:0,C=c&&!v?g/2-i:0,k=i,T=m?"bottom":"top",D=2*i,x=D,S=_/2-x/2,I=g/2-D/2;this.wrapper.style.top=u?y+"px":"",this.wrapper.style.right=p?a-f-g-r+"px":"",this.wrapper.style.bottom=m?l-y-_+"px":"",this.wrapper.style.left=c?f+"px":"",this.wrapper.style.position=E,this.contentEl.style.width=w+"px",this.contentEl.style.height=b+"px",this.contentEl.style.top=L+"px",this.contentEl.style.right="0px",this.contentEl.style.bottom="0px",this.contentEl.style.left=C+"px",this.contentEl.style.padding=k+"px",this.contentEl.style.verticalAlign=T,this.waveEl.style.top=S+"px",this.waveEl.style.left=I+"px",this.waveEl.style.width=D+"px",this.waveEl.style.height=x+"px"}open=()=>{this.isOpen||("function"==typeof this.options.onOpen&&this.options.onOpen.call(this,this.originEl),this.isOpen=!0,this.wrapper.classList.add("open"),this.wrapper.ariaExpanded="true",document.body.addEventListener("click",this._handleDocumentClick,!0),document.body.addEventListener("keypress",this._handleDocumentClick,!0),document.body.addEventListener("touchend",this._handleDocumentClick))};close=()=>{this.isOpen&&("function"==typeof this.options.onClose&&this.options.onClose.call(this,this.originEl),this.isOpen=!1,this.wrapper.classList.remove("open"),this.wrapper.ariaExpanded="false",document.body.removeEventListener("click",this._handleDocumentClick,!0),document.body.removeEventListener("keypress",this._handleDocumentClick,!0),document.body.removeEventListener("touchend",this._handleDocumentClick))};static{Y._taptargets=[]}}const j=Object.freeze({});class U extends i{counterEl;isInvalid;isValidLength;constructor(t,e){super(t,{},U),this.el.M_CharacterCounter=this,this.options={...U.defaults,...e},this.isInvalid=!1,this.isValidLength=!1,this._setupCounter(),this._setupEventHandlers()}static get defaults(){return j}static init(t,e={}){return super.init(t,e,U)}static getInstance(t){return t.M_CharacterCounter}destroy(){this._removeEventHandlers(),this.el.CharacterCounter=void 0,this._removeCounter()}_setupEventHandlers(){this.el.addEventListener("focus",this.updateCounter,!0),this.el.addEventListener("input",this.updateCounter,!0)}_removeEventHandlers(){this.el.removeEventListener("focus",this.updateCounter,!0),this.el.removeEventListener("input",this.updateCounter,!0)}_setupCounter(){this.counterEl=document.createElement("span"),this.counterEl.classList.add("character-counter"),this.counterEl.style.float="right",this.counterEl.style.fontSize="12px",this.counterEl.style.height="1",this.el.parentElement.appendChild(this.counterEl)}_removeCounter(){this.counterEl.remove()}updateCounter=()=>{const t=parseInt(this.el.getAttribute("maxlength")),e=this.el.value.length;this.isValidLength=e<=t;let i=e.toString();t&&(i+="/"+t,this._validateInput()),this.counterEl.innerHTML=i};_validateInput(){this.isValidLength&&this.isInvalid?(this.isInvalid=!1,this.el.classList.remove("invalid")):this.isValidLength||this.isInvalid||(this.isInvalid=!0,this.el.classList.remove("valid"),this.el.classList.add("invalid"))}}const Z={responsiveThreshold:0};class G extends i{_enabled;_img;static _parallaxes=[];static _handleScrollThrottled;static _handleWindowResizeThrottled;constructor(t,e){super(t,e,G),this.el.M_Parallax=this,this.options={...G.defaults,...e},this._enabled=window.innerWidth>this.options.responsiveThreshold,this._img=this.el.querySelector("img"),this._updateParallax(),this._setupEventHandlers(),this._setupStyles(),G._parallaxes.push(this)}static get defaults(){return Z}static init(t,e={}){return super.init(t,e,G)}static getInstance(t){return t.M_Parallax}destroy(){G._parallaxes.splice(G._parallaxes.indexOf(this),1),this._img.style.transform="",this._removeEventHandlers(),this.el.M_Parallax=void 0}static _handleScroll(){for(let t=0;te.options.responsiveThreshold}}_setupEventHandlers(){this._img.addEventListener("load",this._handleImageLoad),0===G._parallaxes.length&&(G._handleScrollThrottled||(G._handleScrollThrottled=e.throttle(G._handleScroll,5)),G._handleWindowResizeThrottled||(G._handleWindowResizeThrottled=e.throttle(G._handleWindowResize,5)),window.addEventListener("scroll",G._handleScrollThrottled),window.addEventListener("resize",G._handleWindowResizeThrottled))}_removeEventHandlers(){this._img.removeEventListener("load",this._handleImageLoad),0===G._parallaxes.length&&(window.removeEventListener("scroll",G._handleScrollThrottled),window.removeEventListener("resize",G._handleWindowResizeThrottled))}_setupStyles(){this._img.style.opacity="1"}_handleImageLoad=()=>{this._updateParallax()};_offset(t){const e=t.getBoundingClientRect(),i=document.documentElement;return{top:e.top+window.scrollY-i.clientTop,left:e.left+window.scrollX-i.clientLeft}}_updateParallax(){const t=this.el.getBoundingClientRect().height>0?this.el.parentElement.offsetHeight:500,i=this._img.offsetHeight-t,s=this._offset(this.el).top+t,n=this._offset(this.el).top,o=e.getDocumentScrollTop(),a=window.innerHeight,l=i*((o+a-n)/(t+a));this._enabled?s>o&&n=t&&!this.el.classList.contains("pinned")&&(this._removePinClasses(),this.el.style.top=`${this.options.offset}px`,this.el.classList.add("pinned"),"function"==typeof this.options.onPositionChange&&this.options.onPositionChange.call(this,"pinned")),tthis.options.bottom&&!this.el.classList.contains("pin-bottom")&&(this._removePinClasses(),this.el.classList.add("pin-bottom"),this.el.style.top=this.options.bottom-this.originalOffset+"px","function"==typeof this.options.onPositionChange&&this.options.onPositionChange.call(this,"pin-bottom"))}_removePinClasses(){this.el.classList.remove("pin-top"),this.el.classList.remove("pinned"),this.el.classList.remove("pin-bottom")}static{J._pushpins=[]}}const tt={throttle:100,scrollOffset:200,activeClass:"active",getActiveElement:t=>'a[href="#'+t+'"]',keepTopElementActive:!1,animationDuration:null};class et extends i{static _elements;static _count;static _increment;static _elementsInView;static _visibleElements;static _ticks;static _keptTopActiveElement=null;tickId;id;constructor(t,e){super(t,e,et),this.el.M_ScrollSpy=this,this.options={...et.defaults,...e},et._elements.push(this),et._count++,et._increment++,this.tickId=-1,this.id=et._increment.toString(),this._setupEventHandlers(),this._handleWindowScroll()}static get defaults(){return tt}static init(t,e={}){return super.init(t,e,et)}static getInstance(t){return t.M_ScrollSpy}destroy(){et._elements.splice(et._elements.indexOf(this),1),et._elementsInView.splice(et._elementsInView.indexOf(this),1),et._visibleElements.splice(et._visibleElements.indexOf(this.el),1),et._count--,this._removeEventHandlers();document.querySelector(this.options.getActiveElement(this.el.id)).classList.remove(this.options.activeClass),this.el.M_ScrollSpy=void 0}_setupEventHandlers(){1===et._count&&(window.addEventListener("scroll",this._handleWindowScroll),window.addEventListener("resize",this._handleThrottledResize),document.body.addEventListener("click",this._handleTriggerClick))}_removeEventHandlers(){0===et._count&&(window.removeEventListener("scroll",this._handleWindowScroll),window.removeEventListener("resize",this._handleThrottledResize),document.body.removeEventListener("click",this._handleTriggerClick))}_handleThrottledResize=()=>e.throttle(this._handleWindowScroll,200).bind(this);_handleTriggerClick=t=>{const e=t.target;for(let i=et._elements.length-1;i>=0;i--){const s=et._elements[i];if(e===document.querySelector('a[href="#'+s.el.id+'"]')){t.preventDefault(),s.el.M_ScrollSpy.options.animationDuration?et._smoothScrollIntoView(s.el,s.el.M_ScrollSpy.options.animationDuration):s.el.scrollIntoView({behavior:"smooth"});break}}};_handleWindowScroll=()=>{et._ticks++;const t=e.getDocumentScrollTop(),i=e.getDocumentScrollLeft(),s=i+window.innerWidth,n=t+window.innerHeight,o=et._findElements(t,s,n,i);for(let t=0;t=0&&i!==et._ticks&&(e._exit(),e.tickId=-1)}if(et._elementsInView=o,et._elements.length){const t=et._elements[0].el.M_ScrollSpy.options;if(t.keepTopElementActive&&0===et._visibleElements.length){this._resetKeptTopActiveElementIfNeeded();const e=et._elements.filter(t=>et._getDistanceToViewport(t.el)<=0).sort((t,e)=>{const i=et._getDistanceToViewport(t.el),s=et._getDistanceToViewport(e.el);return is?1:0}),i=e.length?e[e.length-1]:et._elements[0],s=document.querySelector(t.getActiveElement(i.el.id));s?.classList.add(t.activeClass),et._keptTopActiveElement=s}}};static _offset(t){const e=t.getBoundingClientRect(),i=document.documentElement;return{top:e.top+window.pageYOffset-i.clientTop,left:e.left+window.pageXOffset-i.clientLeft}}static _findElements(t,e,i,s){const n=[];for(let o=0;o0){const t=et._offset(a.el).top,o=et._offset(a.el).left,r=o+a.el.getBoundingClientRect().width,h=t+a.el.getBoundingClientRect().height;!(o>e||ri||h0!==t.getBoundingClientRect().height),et._visibleElements[0]){const t=document.querySelector(this.options.getActiveElement(et._visibleElements[0].id));t?.classList.remove(this.options.activeClass),et._visibleElements[0].M_ScrollSpy&&this.id0!==t.getBoundingClientRect().height),et._visibleElements[0]){const t=document.querySelector(this.options.getActiveElement(et._visibleElements[0].id));if(t?.classList.remove(this.options.activeClass),et._visibleElements=et._visibleElements.filter(t=>t.id!=this.el.id),et._visibleElements[0]){const t=this.options.getActiveElement(et._visibleElements[0].id);document.querySelector(t)?.classList.add(this.options.activeClass),this._resetKeptTopActiveElementIfNeeded()}}}_resetKeptTopActiveElementIfNeeded(){et._keptTopActiveElement&&(et._keptTopActiveElement.classList.remove(this.options.activeClass),et._keptTopActiveElement=null)}static _getDistanceToViewport(t){return t.getBoundingClientRect().top}static _smoothScrollIntoView(t,e=300){const i=t.getBoundingClientRect().top+(window.scrollY||window.pageYOffset),s=window.scrollY||window.pageYOffset,n=i-s,o=performance.now();requestAnimationFrame(function t(a){const l=a-o,r=Math.min(l/e,1),h=s+n*r;r<1?(window.scrollTo(0,h),requestAnimationFrame(t)):window.scrollTo(0,i)})}static{et._elements=[],et._elementsInView=[],et._visibleElements=[],et._count=0,et._increment=0,et._ticks=0}}class it{static#z(t){const e=t.getBoundingClientRect(),i=document.documentElement;return{top:e.top+window.pageYOffset-i.clientTop,left:e.left+window.pageXOffset-i.clientLeft}}static renderWaveEffect(t,e=null,i=null){const s=null===e;let n,o;const a=l=>{o||(o=l);const r=l-o;if(r<500){const o=r/500*(2-r/500),l=s?"circle at 50% 50%":`circle at ${e.x}px ${e.y}px`,h=`rgba(${i?.r||0}, ${i?.g||0}, ${i?.b||0}, ${.3*(1-o)})`,d=90*o+"%";t.style.backgroundImage="radial-gradient("+l+", "+h+" "+d+", transparent "+d+")",n=window.requestAnimationFrame(a)}else t.style.backgroundImage="none",window.cancelAnimationFrame(n)};n=window.requestAnimationFrame(a)}static Init(){"undefined"!=typeof document&&document?.addEventListener("DOMContentLoaded",()=>{document.body.addEventListener("click",t=>{const e=t.target,i=e.closest(".waves-effect");if(i&&i.contains(e)){const e=i.classList.contains("waves-circle"),s=t.pageX-this.#z(i).left,n=t.pageY-this.#z(i).top;let o=null;i.classList.contains("waves-light")&&(o={r:255,g:255,b:255}),this.renderWaveEffect(i,e?null:{x:s,y:n},o)}})})}}return"undefined"!=typeof document&&(document.addEventListener("keydown",e.docHandleKeydown,!0),document.addEventListener("keyup",e.docHandleKeyup,!0),document.addEventListener("focus",e.docHandleFocus,!0),document.addEventListener("blur",e.docHandleBlur,!0)),D.Init(),g.Init(),it.Init(),X.Init(),d.Init(),t.AutoInit=function(t=document.body,e){const i={Autocomplete:t.querySelectorAll(".autocomplete:not(.no-autoinit)"),Cards:t.querySelectorAll(".cards:not(.no-autoinit)"),Carousel:t.querySelectorAll(".carousel:not(.no-autoinit)"),Chips:t.querySelectorAll(".chips:not(.no-autoinit)"),Collapsible:t.querySelectorAll(".collapsible:not(.no-autoinit)"),Datepicker:t.querySelectorAll(".datepicker:not(.no-autoinit)"),Dropdown:t.querySelectorAll(".dropdown-trigger:not(.no-autoinit)"),Materialbox:t.querySelectorAll(".materialboxed:not(.no-autoinit)"),Modal:t.querySelectorAll(".modal:not(.no-autoinit)"),Parallax:t.querySelectorAll(".parallax:not(.no-autoinit)"),Pushpin:t.querySelectorAll(".pushpin:not(.no-autoinit)"),ScrollSpy:t.querySelectorAll(".scrollspy:not(.no-autoinit)"),FormSelect:t.querySelectorAll("select:not(.no-autoinit)"),Sidenav:t.querySelectorAll(".sidenav:not(.no-autoinit)"),Tabs:t.querySelectorAll(".tabs:not(.no-autoinit)"),TapTarget:t.querySelectorAll(".tap-target:not(.no-autoinit)"),Timepicker:t.querySelectorAll(".timepicker:not(.no-autoinit)"),Tooltip:t.querySelectorAll(".tooltipped:not(.no-autoinit)"),FloatingActionButton:t.querySelectorAll(".fixed-action-btn:not(.no-autoinit)")};a.init(i.Autocomplete,e?.Autocomplete??{}),d.init(i.Cards,e?.Cards??{}),p.init(i.Carousel,e?.Carousel??{}),g.init(i.Chips,e?.Chips??{}),y.init(i.Collapsible,e?.Collapsible??{}),T.init(i.Datepicker,e?.Datepicker??{}),n.init(i.Dropdown,e?.Dropdown??{}),S.init(i.Materialbox,e?.Materialbox??{}),A.init(i.Modal,e?.Modal??{}),G.init(i.Parallax,e?.Parallax??{}),J.init(i.Pushpin,e?.Pushpin??{}),et.init(i.ScrollSpy,e?.ScrollSpy??{}),E.init(i.FormSelect,e?.FormSelect??{}),O.init(i.Sidenav,e?.Sidenav??{}),W.init(i.Tabs,e?.Tabs??{}),Y.init(i.TapTarget,e?.TapTarget??{}),q.init(i.Timepicker,e?.Timepicker??{}),N.init(i.Tooltip,e?.Tooltip??{}),r.init(i.FloatingActionButton,e?.FloatingActionButton??{})},t.Autocomplete=a,t.Cards=d,t.Carousel=p,t.CharacterCounter=U,t.Chips=g,t.Collapsible=y,t.Datepicker=T,t.Dropdown=n,t.FloatingActionButton=r,t.FormSelect=E,t.Forms=D,t.Materialbox=S,t.Modal=A,t.Parallax=G,t.Pushpin=J,t.Range=X,t.ScrollSpy=et,t.Sidenav=O,t.Slider=H,t.Tabs=W,t.TapTarget=Y,t.Timepicker=q,t.Toast=V,t.Tooltip=N,t.Waves=it,t.version="2.3.3",t}({}); diff --git a/dist/js/materialize.mjs b/dist/js/materialize.mjs deleted file mode 100644 index 626a45c4f8..0000000000 --- a/dist/js/materialize.mjs +++ /dev/null @@ -1,8376 +0,0 @@ -/*! -* Materialize v2.3.3 (https://materializeweb.com) -* Copyright 2014-2026 Materialize -* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE) -*/ -/** - * Class with utilitary functions for global usage. - */ -class Utils { - /** Specifies wether tab is pressed or not. */ - static tabPressed = false; - /** Specifies wether there is a key pressed. */ - static keyDown = false; - /** - * Key maps. - */ - static keys = { - TAB: ['Tab'], - ENTER: ['Enter'], - ESC: ['Escape', 'Esc'], - BACKSPACE: ['Backspace'], - ARROW_UP: ['ArrowUp', 'Up'], - ARROW_DOWN: ['ArrowDown', 'Down'], - ARROW_LEFT: ['ArrowLeft', 'Left'], - ARROW_RIGHT: ['ArrowRight', 'Right'], - DELETE: ['Delete', 'Del'] - }; - /** - * Detects when a key is pressed. - * @param e Event instance. - */ - static docHandleKeydown(e) { - Utils.keyDown = true; - if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) { - Utils.tabPressed = true; - } - } - /** - * Detects when a key is released. - * @param e Event instance. - */ - static docHandleKeyup(e) { - Utils.keyDown = false; - if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) { - Utils.tabPressed = false; - } - } - /** - * Detects when document is focused. - * @param e Event instance. - */ - /* eslint-disabled as of required event type condition check */ - /* eslint-disable-next-line */ - static docHandleFocus(e) { - if (Utils.keyDown) { - document.body.classList.add('keyboard-focused'); - } - } - /** - * Detects when document is not focused. - * @param e Event instance. - */ - /* eslint-disabled as of required event type condition check */ - /* eslint-disable-next-line */ - static docHandleBlur(e) { - document.body.classList.remove('keyboard-focused'); - } - /** - * Generates a unique string identifier. - */ - static guid() { - const s4 = () => { - return Math.floor((1 + Math.random()) * 0x10000) - .toString(16) - .substring(1); - }; - return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); - } - /** - * Checks for exceeded edges - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkWithinContainer(container, bounding, offset) { - const edges = { - top: false, - right: false, - bottom: false, - left: false - }; - const containerRect = container.getBoundingClientRect(); - // If body element is smaller than viewport, use viewport height instead. - const containerBottom = container === document.body - ? Math.max(containerRect.bottom, window.innerHeight) - : containerRect.bottom; - const scrollLeft = container.scrollLeft; - const scrollTop = container.scrollTop; - const scrolledX = bounding.left - scrollLeft; - const scrolledY = bounding.top - scrollTop; - // Check for container and viewport for each edge - if (scrolledX < containerRect.left + offset || scrolledX < offset) { - edges.left = true; - } - if (scrolledX + bounding.width > containerRect.right - offset || - scrolledX + bounding.width > window.innerWidth - offset) { - edges.right = true; - } - if (scrolledY < containerRect.top + offset || scrolledY < offset) { - edges.top = true; - } - if (scrolledY + bounding.height > containerBottom - offset || - scrolledY + bounding.height > window.innerHeight - offset) { - edges.bottom = true; - } - return edges; - } - /** - * Checks if element can be aligned in multiple directions. - * @param el Element to be inspected. - * @param container Container element. - * @param bounding Bounding rect. - * @param offset Element offset. - */ - static checkPossibleAlignments(el, container, bounding, offset) { - const canAlign = { - top: true, - right: true, - bottom: true, - left: true, - spaceOnTop: null, - spaceOnRight: null, - spaceOnBottom: null, - spaceOnLeft: null - }; - const containerAllowsOverflow = getComputedStyle(container).overflow === 'visible'; - const containerRect = container.getBoundingClientRect(); - const containerHeight = Math.min(containerRect.height, window.innerHeight); - const containerWidth = Math.min(containerRect.width, window.innerWidth); - const elOffsetRect = el.getBoundingClientRect(); - const scrollLeft = container.scrollLeft; - const scrollTop = container.scrollTop; - const scrolledX = bounding.left - scrollLeft; - const scrolledYTopEdge = bounding.top - scrollTop; - const scrolledYBottomEdge = bounding.top + elOffsetRect.height - scrollTop; - // Check for container and viewport for left - canAlign.spaceOnRight = !containerAllowsOverflow - ? containerWidth - (scrolledX + bounding.width) - : window.innerWidth - (elOffsetRect.left + bounding.width); - if (canAlign.spaceOnRight < 0) { - canAlign.left = false; - } - // Check for container and viewport for Right - canAlign.spaceOnLeft = !containerAllowsOverflow - ? scrolledX - bounding.width + elOffsetRect.width - : elOffsetRect.right - bounding.width; - if (canAlign.spaceOnLeft < 0) { - canAlign.right = false; - } - // Check for container and viewport for Top - canAlign.spaceOnBottom = !containerAllowsOverflow - ? containerHeight - (scrolledYTopEdge + bounding.height + offset) - : window.innerHeight - (elOffsetRect.top + bounding.height + offset); - if (canAlign.spaceOnBottom < 0) { - canAlign.top = false; - } - // Check for container and viewport for Bottom - canAlign.spaceOnTop = !containerAllowsOverflow - ? scrolledYBottomEdge - (bounding.height - offset) - : elOffsetRect.bottom - (bounding.height + offset); - if (canAlign.spaceOnTop < 0) { - canAlign.bottom = false; - } - return canAlign; - } - /** - * Retrieves target element id from trigger. - * @param trigger Trigger element. - */ - static getIdFromTrigger(trigger) { - let id = trigger.dataset.target; - if (!id) { - id = trigger.getAttribute('href'); - return id ? id.slice(1) : ''; - } - return id; - } - /** - * Retrieves document scroll postion from top. - */ - static getDocumentScrollTop() { - return window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0; - } - /** - * Retrieves document scroll postion from left. - */ - static getDocumentScrollLeft() { - return window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft || 0; - } - /** - * Fires the given function after a certain ammount of time. - * @param func Function to be fired. - * @param wait Wait time. - * @param options Additional options. - */ - static throttle(func, wait, options = {}) { - let context, args, result, timeout = null, previous = 0; - const later = () => { - previous = options.leading === false ? 0 : new Date().getTime(); - timeout = null; - result = func.apply(context, args); - context = args = null; - }; - return (...args) => { - const now = new Date().getTime(); - if (!previous && options.leading === false) - previous = now; - const remaining = wait - (now - previous); - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(this, args); - } - else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - } - /** - * Renders confirm/close buttons with callback function - */ - static createConfirmationContainer(container, confirmText, cancelText, onConfirm, onCancel) { - const confirmationButtonsContainer = document.createElement('div'); - confirmationButtonsContainer.classList.add('confirmation-btns'); - container.append(confirmationButtonsContainer); - this.createButton(confirmationButtonsContainer, cancelText, ['btn-cancel'], true, onCancel); - this.createButton(confirmationButtonsContainer, confirmText, ['btn-confirm'], true, onConfirm); - } - /** - * Renders a button with optional callback function - */ - static createButton(container, text, className = [], visibility = true, callback = null) { - className = className.concat(['btn', 'waves-effect', 'text']); - const button = document.createElement('button'); - button.className = className.join(' '); - button.style.visibility = visibility ? 'visible' : 'hidden'; - button.type = 'button'; - button.tabIndex = !!visibility ? 0 : -1; - button.innerText = text; - button.addEventListener('click', callback); - button.addEventListener('keypress', (e) => { - if (Utils.keys.ENTER.includes(e.key)) - callback(e); - }); - container.append(button); - } - static _setAbsolutePosition(origin, container, position, margin, transitionMovement, align = 'center') { - const originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, containerHeight = container.offsetHeight, containerWidth = container.offsetWidth; - let xMovement = 0, yMovement = 0, targetTop = origin.getBoundingClientRect().top + Utils.getDocumentScrollTop(), targetLeft = origin.getBoundingClientRect().left + Utils.getDocumentScrollLeft(); - if (position === 'top') { - targetTop += -containerHeight - margin; - if (align === 'center') { - targetLeft += originWidth / 2 - containerWidth / 2; // This is center align - } - yMovement = -transitionMovement; - } - else if (position === 'right') { - targetTop += originHeight / 2 - containerHeight / 2; - targetLeft = originWidth + margin; - xMovement = transitionMovement; - } - else if (position === 'left') { - targetTop += originHeight / 2 - containerHeight / 2; - targetLeft = -containerWidth - margin; - xMovement = -transitionMovement; - } - else { - targetTop += originHeight + margin; - if (align === 'center') { - targetLeft += originWidth / 2 - containerWidth / 2; // This is center align - } - yMovement = transitionMovement; - } - if (align === 'right') { - targetLeft += originWidth - containerWidth - margin; - } - const newCoordinates = Utils._repositionWithinScreen(targetLeft, targetTop, containerWidth, containerHeight, margin, transitionMovement, align); - container.style.top = newCoordinates.y + 'px'; - container.style.left = newCoordinates.x + 'px'; - return { x: xMovement, y: yMovement }; - } - static _repositionWithinScreen(x, y, width, height, margin, transitionMovement, align) { - const scrollLeft = Utils.getDocumentScrollLeft(); - const scrollTop = Utils.getDocumentScrollTop(); - let newX = x - scrollLeft; - let newY = y - scrollTop; - const bounding = { - left: newX, - top: newY, - width: width, - height: height - }; - let offset; - if (align === 'left' || align == 'center') { - offset = margin + transitionMovement; - } - else if (align === 'right') { - offset = margin - transitionMovement; - } - const edges = Utils.checkWithinContainer(document.body, bounding, offset); - if (edges.left) { - newX = offset; - } - else if (edges.right) { - newX -= newX + width - window.innerWidth; - } - if (edges.top) { - newY = offset; - } - else if (edges.bottom) { - newY -= newY + height - window.innerHeight; - } - return { - x: newX + scrollLeft, - y: newY + scrollTop - }; - } -} - -/** - * Base class implementation for Materialize components. - */ -class Component { - /** - * The DOM element the plugin was initialized with. - */ - el; - /** - * The options the instance was initialized with. - */ - options; - /** - * Constructs component instance and set everything up. - */ - constructor(el, options, classDef) { - // Display error if el is not a valid HTML Element - if (!(el instanceof HTMLElement)) { - console.error(Error(el + ' is not an HTML Element')); - } - // If exists, destroy and reinitialize in child - const ins = classDef.getInstance(el); - if (!!ins) { - ins.destroy(); - } - this.el = el; - } - /** - * Initializes component instances. - * @param els HTML elements. - * @param options Component options. - * @param classDef Class definition. - */ - static init(els, options, classDef) { - let instances = null; - if (els instanceof Element) { - instances = new classDef(els, options); - } - else if (!!els && els.length) { - instances = []; - for (let i = 0; i < els.length; i++) { - instances.push(new classDef(els[i], options)); - } - } - return instances; - } - /** - * @returns default options for component instance. - */ - static get defaults() { - return {}; - } - /** - * Retrieves component instance for the given element. - * @param el Associated HTML Element. - */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - static getInstance(el) { - throw new Error('This method must be implemented.'); - } - /** - * Destroy plugin instance and teardown. - */ - destroy() { - throw new Error('This method must be implemented.'); - } -} - -const _defaults$o = { - alignment: 'left', - autoFocus: true, - constrainWidth: true, - container: null, - coverTrigger: true, - closeOnClick: true, - hover: false, - inDuration: 150, - outDuration: 250, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - onItemClick: null -}; -class Dropdown extends Component { - static _dropdowns = []; - /** ID of the dropdown element. */ - id; - /** The DOM element of the dropdown. */ - dropdownEl; - /** If the dropdown is open. */ - isOpen; - /** If the dropdown content is scrollable. */ - isScrollable; - isTouchMoving; - /** The index of the item focused. */ - focusedIndex; - filterQuery; - filterTimeout; - constructor(el, options) { - super(el, options, Dropdown); - this.el['M_Dropdown'] = this; - Dropdown._dropdowns.push(this); - this.id = Utils.getIdFromTrigger(el); - this.dropdownEl = document.getElementById(this.id); - this.options = { - ...Dropdown.defaults, - ...options - }; - this.isOpen = false; - this.isScrollable = false; - this.isTouchMoving = false; - this.focusedIndex = -1; - this.filterQuery = []; - this.el.ariaExpanded = 'false'; - // Move dropdown-content after dropdown-trigger - this._moveDropdownToElement(); - this._makeDropdownFocusable(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$o; - } - /** - * Initializes instances of Dropdown. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Dropdown); - } - static getInstance(el) { - return el['M_Dropdown']; - } - destroy() { - this._resetDropdownStyles(); - this._removeEventHandlers(); - Dropdown._dropdowns.splice(Dropdown._dropdowns.indexOf(this), 1); - this.el['M_Dropdown'] = undefined; - } - _setupEventHandlers() { - // Trigger keydown handler - this.el.addEventListener('keydown', this._handleTriggerKeydown); - // Item click handler - this.dropdownEl?.addEventListener('click', this._handleDropdownClick); - // Hover event handlers - if (this.options.hover) { - this.el.addEventListener('mouseenter', this._handleMouseEnter); - this.el.addEventListener('mouseleave', this._handleMouseLeave); - this.dropdownEl.addEventListener('mouseleave', this._handleMouseLeave); - // Click event handlers - } - else { - this.el.addEventListener('click', this._handleClick); - } - } - _removeEventHandlers() { - this.el.removeEventListener('keydown', this._handleTriggerKeydown); - this.dropdownEl.removeEventListener('click', this._handleDropdownClick); - if (this.options.hover) { - this.el.removeEventListener('mouseenter', this._handleMouseEnter); - this.el.removeEventListener('mouseleave', this._handleMouseLeave); - this.dropdownEl.removeEventListener('mouseleave', this._handleMouseLeave); - } - else { - this.el.removeEventListener('click', this._handleClick); - } - } - _setupTemporaryEventHandlers() { - document.body.addEventListener('click', this._handleDocumentClick); - document.body.addEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.addEventListener('keydown', this._handleDropdownKeydown); - window.addEventListener('resize', this._handleWindowResize); - } - _removeTemporaryEventHandlers() { - document.body.removeEventListener('click', this._handleDocumentClick); - document.body.removeEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.removeEventListener('keydown', this._handleDropdownKeydown); - window.removeEventListener('resize', this._handleWindowResize); - } - _handleClick = (e) => { - e.preventDefault(); - //this._moveDropdown((e.target).closest('li')); - if (this.isOpen) { - this.close(); - } - else { - this.open(); - } - }; - _handleMouseEnter = () => { - //this._moveDropdown((e.target).closest('li')); - this.open(); - }; - _handleMouseLeave = (e) => { - const toEl = e.relatedTarget; - const leaveToDropdownContent = !!toEl.closest('.dropdown-content'); - let leaveToActiveDropdownTrigger = false; - const closestTrigger = toEl.closest('.dropdown-trigger'); - if (closestTrigger && !!closestTrigger['M_Dropdown'] && closestTrigger['M_Dropdown'].isOpen) { - leaveToActiveDropdownTrigger = true; - } - // Close hover dropdown if mouse did not leave to either active dropdown-trigger or dropdown-content - if (!leaveToActiveDropdownTrigger && !leaveToDropdownContent) { - this.close(); - } - }; - _handleDocumentClick = (e) => { - const target = e.target; - if (this.options.closeOnClick && target.closest('.dropdown-content') && !this.isTouchMoving) { - // isTouchMoving to check if scrolling on mobile. - this.close(); - } - else if (!target.closest('.dropdown-content')) { - // Do this one frame later so that if the element clicked also triggers _handleClick - // For example, if a label for a select was clicked, that we don't close/open the dropdown - setTimeout(() => { - if (this.isOpen) { - this.close(); - } - }, 0); - } - this.isTouchMoving = false; - }; - _handleTriggerKeydown = (e) => { - // ARROW DOWN OR ENTER WHEN SELECT IS CLOSED - open Dropdown - const arrowDownOrEnter = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ENTER.includes(e.key); - if (arrowDownOrEnter && !this.isOpen) { - e.preventDefault(); - this.open(); - } - }; - _handleDocumentTouchmove = (e) => { - const target = e.target; - if (target.closest('.dropdown-content')) { - this.isTouchMoving = true; - } - }; - _handleDropdownClick = (e) => { - // onItemClick callback - if (typeof this.options.onItemClick === 'function') { - const itemEl = e.target.closest('li'); - this.options.onItemClick.call(this, itemEl); - } - }; - _handleDropdownKeydown = (e) => { - const arrowUpOrDown = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ARROW_UP.includes(e.key); - if (Utils.keys.TAB.includes(e.key)) { - e.preventDefault(); - this.close(); - } - // Navigate down dropdown list - else if (arrowUpOrDown && this.isOpen) { - e.preventDefault(); - const direction = Utils.keys.ARROW_DOWN.includes(e.key) ? 1 : -1; - let newFocusedIndex = this.focusedIndex; - let hasFoundNewIndex = false; - do { - newFocusedIndex = newFocusedIndex + direction; - if (!!this.dropdownEl.children[newFocusedIndex] && - this.dropdownEl.children[newFocusedIndex].tabIndex !== -1) { - hasFoundNewIndex = true; - break; - } - } while (newFocusedIndex < this.dropdownEl.children.length && newFocusedIndex >= 0); - if (hasFoundNewIndex) { - // Remove active class from old element - if (this.focusedIndex >= 0) - this.dropdownEl.children[this.focusedIndex].classList.remove('active'); - this.focusedIndex = newFocusedIndex; - this._focusFocusedItem(); - } - } - // ENTER selects choice on focused item - else if (Utils.keys.ENTER.includes(e.key) && this.isOpen) { - // Search for
and ` + - ''); - } - renderRow(days, isRTL, isRowSelected) { - return ('' + - (isRTL ? days.reverse() : days).join('') + - ''); - } - renderTable(opts, data, randId) { - return ('
' + - this.renderHead(opts) + - this.renderBody(data) + - '
'); - } - renderHead(opts) { - const arr = []; - let i; - for (i = 0; i < 7; i++) { - arr.push(`${this.renderDayName(opts, i, true)}`); - } - return '' + (opts.isRTL ? arr.reverse() : arr).join('') + ''; - } - renderBody(rows) { - return '' + rows.join('') + ''; - } - renderTitle(instance, c, year, month, refYear, randId) { - const opts = this.options, isMinYear = year === opts.minYear, isMaxYear = year === opts.maxYear; - let i, j, arr = [], html = '
', prev = true, next = true; - for (i = 0; i < 12; i++) { - arr.push(''); - } - const monthHtml = ''; - if (Array.isArray(opts.yearRange)) { - i = opts.yearRange[0]; - j = opts.yearRange[1] + 1; - } - else { - i = year - opts.yearRange; - j = 1 + year + opts.yearRange; - } - for (arr = []; i < j && i <= opts.maxYear; i++) { - if (i >= opts.minYear) { - arr.push(``); - } - } - if (opts.yearRangeReverse) - arr.reverse(); - const yearHtml = ``; - const leftArrow = ''; - html += ``; - html += '
'; - if (opts.showMonthAfterYear) { - html += yearHtml + monthHtml; - } - else { - html += monthHtml + yearHtml; - } - html += '
'; - if (isMinYear && (month === 0 || opts.minMonth >= month)) { - prev = false; - } - if (isMaxYear && (month === 11 || opts.maxMonth <= month)) { - next = false; - } - const rightArrow = ''; - html += ``; - return (html += '
'); - } - // refresh HTML - draw() { - const opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth; - let html = ''; - if (this._y <= minYear) { - this._y = minYear; - if (!isNaN(minMonth) && this._m < minMonth) { - this._m = minMonth; - } - } - if (this._y >= maxYear) { - this._y = maxYear; - if (!isNaN(maxMonth) && this._m > maxMonth) { - this._m = maxMonth; - } - } - const randId = 'datepicker-title-' + - Math.random() - .toString(36) - .replace(/[^a-z]+/g, '') - .substr(0, 2); - for (let c = 0; c < 1; c++) { - if (!this.options.isDateRange) { - this._renderDateDisplay(this.date); - } - else { - this._renderDateDisplay(this.date, this.endDate); - } - html += - this.renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId); - } - this.destroySelects(); - this.calendarEl.innerHTML = html; - // Init Materialize Select - const yearSelect = this.calendarEl.querySelector('.orig-select-year'); - const monthSelect = this.calendarEl.querySelector('.orig-select-month'); - // @todo fix accessibility @see https://github.com/materializecss/materialize/issues/522 - FormSelect.init(yearSelect, { - classes: 'select-year', - dropdownOptions: { container: document.body, constrainWidth: false } - }); - FormSelect.init(monthSelect, { - classes: 'select-month', - dropdownOptions: { container: document.body, constrainWidth: false } - }); - // Add change handlers for select - yearSelect.addEventListener('change', this._handleYearChange); - monthSelect.addEventListener('change', this._handleMonthChange); - if (typeof this.options.onDraw === 'function') { - this.options.onDraw.call(this); - } - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleInputClick); - this.el.addEventListener('keydown', this._handleInputKeydown); - this.el.addEventListener('change', this._handleInputChange); - this.calendarEl.addEventListener('click', this._handleCalendarClick); - } - _setupVariables() { - const template = document.createElement('template'); - template.innerHTML = Datepicker._template.trim(); - this.containerEl = template.content.firstChild; - this.calendarEl = this.containerEl.querySelector('.datepicker-calendar'); - this.yearTextEl = this.containerEl.querySelector('.year-text'); - this.dateTextEl = this.containerEl.querySelector('.date-text'); - this.footer = this.containerEl.querySelector('.datepicker-footer'); - this.formats = { - d: (date) => { - return date.getDate(); - }, - dd: (date) => { - const d = date.getDate(); - return (d < 10 ? '0' : '') + d; - }, - ddd: (date) => { - return this.options.i18n.weekdaysShort[date.getDay()]; - }, - dddd: (date) => { - return this.options.i18n.weekdays[date.getDay()]; - }, - m: (date) => { - return date.getMonth() + 1; - }, - mm: (date) => { - const m = date.getMonth() + 1; - return (m < 10 ? '0' : '') + m; - }, - mmm: (date) => { - return this.options.i18n.monthsShort[date.getMonth()]; - }, - mmmm: (date) => { - return this.options.i18n.months[date.getMonth()]; - }, - yy: (date) => { - return ('' + date.getFullYear()).slice(2); - }, - yyyy: (date) => { - return date.getFullYear(); - } - }; - } - _pickerSetup() { - if (!this.options.defaultDate) { - this.options.defaultDate = new Date(Date.parse(this.el.value)); - } - const defDate = this.options.defaultDate; - if (Datepicker._isDate(defDate)) { - if (this.options.setDefaultDate) { - this.setDate(defDate, true); - this.setInputValue(this.el, defDate); - } - else { - this.gotoDate(defDate); - } - } - else { - this.gotoDate(new Date()); - } - if (this.options.isDateRange) { - this.multiple = true; - const defEndDate = this.options.defaultEndDate; - if (Datepicker._isDate(defEndDate)) { - if (this.options.setDefaultEndDate) { - this.setDate(defEndDate, true, true); - this.setInputValue(this.endDateEl, defEndDate); - } - } - } - if (this.options.isMultipleSelection) { - this.multiple = true; - this.dates = []; - this.dateEls = []; - this.dateEls.push(this.el); - } - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleInputClick); - this.el.removeEventListener('keydown', this._handleInputKeydown); - this.el.removeEventListener('change', this._handleInputChange); - this.calendarEl.removeEventListener('click', this._handleCalendarClick); - if (this.options.isDateRange) { - this.endDateEl.removeEventListener('click', this._handleInputClick); - this.endDateEl.removeEventListener('keypress', this._handleInputKeydown); - this.endDateEl.removeEventListener('change', this._handleInputChange); - } - } - _handleInputClick = (e) => { - // Prevents default browser datepicker modal rendering - if (e.type == 'date') { - e.preventDefault(); - } - this.setDateFromInput(e.target); - this.draw(); - this.gotoDate(e.target === this.el ? this.date : this.endDate); - if (this.displayPlugin) - this.displayPlugin.show(); - if (this.options.onInputInteraction) - this.options.onInputInteraction.call(this); - }; - _handleInputKeydown = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this.setDateFromInput(e.target); - this.draw(); - if (this.displayPlugin) - this.displayPlugin.show(); - if (this.options.onInputInteraction) - this.options.onInputInteraction.call(this); - } - }; - _handleCalendarClick = (e) => { - const target = e.target; - if (!target.classList.contains('is-disabled')) { - if (target.classList.contains('datepicker-day-button') && - !target.classList.contains('is-empty') && - !target.parentElement.classList.contains('is-disabled')) { - const selectedDate = new Date(e.target.getAttribute('data-year'), e.target.getAttribute('data-month'), e.target.getAttribute('data-day')); - if (!this.multiple || (this.multiple && this.options.isMultipleSelection)) { - this.setDate(selectedDate); - } - if (this.options.isDateRange) { - const confirmAfterSelection = Datepicker._isDate(this.date) && this.options.autoSubmit; - this._handleDateRangeCalendarClick(selectedDate); - if (confirmAfterSelection) { - this._confirm(); - } - } - if (!this.options.isDateRange && this.options.autoSubmit) - this._confirm(); - } - else if (target.closest('.month-prev')) { - this.prevMonth(); - } - else if (target.closest('.month-next')) { - this.nextMonth(); - } - } - }; - _handleDateRangeCalendarClick = (date) => { - if (this.endDate == null || !Datepicker._compareDates(date, this.endDate)) { - if (Datepicker._isDate(this.date) && Datepicker._comparePastDate(date, this.date)) { - return; - } - this.setDate(date, true, Datepicker._isDate(this.date)); - return; - } - this._clearDates(); - this.draw(); - }; - _handleClearClick = () => { - this._clearDates(); - this.setInputValues(); - }; - _clearDates = () => { - this.date = null; - this.endDate = null; - this.draw(); - }; - _handleMonthChange = (e) => { - this.gotoMonth(e.target.value); - }; - _handleYearChange = (e) => { - this.gotoYear(e.target.value); - }; - // change view to a specific month (zero-index, e.g. 0: January) - gotoMonth(month) { - if (!isNaN(month)) { - this.calendars[0].month = parseInt(month, 10); - this.adjustCalendars(); - } - } - // change view to a specific full year (e.g. "2012") - gotoYear(year) { - if (!isNaN(year)) { - this.calendars[0].year = parseInt(year, 10); - this.adjustCalendars(); - } - } - _handleInputChange = (e) => { - let date; - const el = e.target; - // Prevent change event from being fired when triggered by the plugin - if (e['detail']?.firedBy === this) - return; - // Prevent change event from being fired if an end date is set without a start date - if (el == this.endDateEl && !this.date) - return; - if (this.options.parse) { - date = this.options.parse(e.target.value, typeof this.options.format === 'function' - ? this.options.format(new Date(this.el.value)) - : this.options.format); - } - else { - date = new Date(Date.parse(e.target.value)); - } - if (Datepicker._isDate(date)) { - this.setDate(date, false, el == this.endDateEl, true); - if (e.type == 'date') { - this.setDataDate(e, date); - this.setInputValues(); - } - } - }; - renderDayName(opts, day, abbr = false) { - day += opts.firstDay; - while (day >= 7) { - day -= 7; - } - return abbr ? opts.i18n.weekdaysAbbrev[day] : opts.i18n.weekdays[day]; - } - createDateInput() { - const dateInput = this.el.cloneNode(true); - dateInput.addEventListener('click', this._handleInputClick); - dateInput.addEventListener('keypress', this._handleInputKeydown); - dateInput.addEventListener('change', this._handleInputChange); - this.el.parentElement.appendChild(dateInput); - return dateInput; - } - // Set input value to the selected date and close Datepicker - _finishSelection = () => { - this.setInputValues(); - // Commented out because of function deprecations - // this.close(); - }; - _confirm = () => { - this._finishSelection(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onConfirm === 'function') - this.options.onConfirm.call(this); - }; - _cancel = () => { - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onCancel === 'function') - this.options.onCancel.call(this); - }; - // deprecated - open() { - console.warn('Datepicker.open() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - close() { - console.warn('Datepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - static { - Datepicker._template = ` -
-
- - -
-
-
- -
-
`; - } -} - -class Forms { - /** - * Checks if the label has validation and apply - * the correct class and styles - * @param textfield - */ - static validateField(textfield) { - if (!textfield) { - console.error('No text field element found'); - return; - } - const hasLength = textfield.getAttribute('data-length') !== null; - const lenAttr = parseInt(textfield.getAttribute('data-length')); - const len = textfield.value.length; - if (len === 0 && - textfield.validity.badInput === false && - !textfield.required && - textfield.classList.contains('validate')) { - textfield.classList.remove('invalid'); - } - else if (textfield.classList.contains('validate')) { - // Check for character counter attributes - if ((textfield.validity.valid && hasLength && len <= lenAttr) || - (textfield.validity.valid && !hasLength)) { - textfield.classList.remove('invalid'); - } - else { - textfield.classList.add('invalid'); - } - } - } - /** - * Resizes the given TextArea after updating the - * value content dynamically. - * @param e EventTarget - */ - static textareaAutoResize(e) { - const textarea = e; - // if (!textarea) { - // console.error('No textarea element found'); - // return; - // } - // Textarea Auto Resize - let hiddenDiv = document.querySelector('.hiddendiv'); - if (!hiddenDiv) { - hiddenDiv = document.createElement('div'); - hiddenDiv.classList.add('hiddendiv', 'common'); - document.body.append(hiddenDiv); - } - const style = getComputedStyle(textarea); - // Set font properties of hiddenDiv - const fontFamily = style.fontFamily; //textarea.css('font-family'); - const fontSize = style.fontSize; //textarea.css('font-size'); - const lineHeight = style.lineHeight; //textarea.css('line-height'); - // Firefox can't handle padding shorthand. - const paddingTop = style.paddingTop; //getComputedStyle(textarea).css('padding-top'); - const paddingRight = style.paddingRight; //textarea.css('padding-right'); - const paddingBottom = style.paddingBottom; //textarea.css('padding-bottom'); - const paddingLeft = style.paddingLeft; //textarea.css('padding-left'); - if (fontSize) - hiddenDiv.style.fontSize = fontSize; //('font-size', fontSize); - if (fontFamily) - hiddenDiv.style.fontFamily = fontFamily; //css('font-family', fontFamily); - if (lineHeight) - hiddenDiv.style.lineHeight = lineHeight; //css('line-height', lineHeight); - if (paddingTop) - hiddenDiv.style.paddingTop = paddingTop; //ss('padding-top', paddingTop); - if (paddingRight) - hiddenDiv.style.paddingRight = paddingRight; //css('padding-right', paddingRight); - if (paddingBottom) - hiddenDiv.style.paddingBottom = paddingBottom; //css('padding-bottom', paddingBottom); - if (paddingLeft) - hiddenDiv.style.paddingLeft = paddingLeft; //css('padding-left', paddingLeft); - // Set original-height, if none - if (!textarea.hasAttribute('original-height')) - textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString()); - if (textarea.getAttribute('wrap') === 'off') { - hiddenDiv.style.overflowWrap = 'normal'; // ('overflow-wrap', 'normal') - hiddenDiv.style.whiteSpace = 'pre'; //.css('white-space', 'pre'); - } - hiddenDiv.innerText = textarea.value + '\n'; - hiddenDiv.innerHTML = hiddenDiv.innerHTML.replace(/\n/g, '
'); - // When textarea is hidden, width goes crazy. - // Approximate with half of window size - if (textarea.offsetWidth > 0 && textarea.offsetHeight > 0) { - hiddenDiv.style.width = textarea.getBoundingClientRect().width + 'px'; // ('width', textarea.width() + 'px'); - } - else { - hiddenDiv.style.width = window.innerWidth / 2 + 'px'; //css('width', window.innerWidth / 2 + 'px'); - } - // Resize if the new height is greater than the - // original height of the textarea - const originalHeight = parseInt(textarea.getAttribute('original-height')); - const prevLength = parseInt(textarea.getAttribute('previous-length')); - if (isNaN(originalHeight)) - return; - if (originalHeight <= hiddenDiv.clientHeight) { - textarea.style.height = hiddenDiv.clientHeight + 'px'; //css('height', hiddenDiv.innerHeight() + 'px'); - } - else if (textarea.value.length < prevLength) { - // In case the new height is less than original height, it - // means the textarea has less text than before - // So we set the height to the original one - textarea.style.height = originalHeight + 'px'; - } - textarea.setAttribute('previous-length', (textarea.value || '').length.toString()); - } - static Init() { - if (typeof document !== 'undefined') - document?.addEventListener('DOMContentLoaded', () => { - document.addEventListener('change', (e) => { - const target = e.target; - if (target instanceof HTMLInputElement) { - if (target.value.length !== 0 || target.getAttribute('placeholder') !== null) { - for (const child of target.parentNode.children) { - if (child.tagName == 'label') { - child.classList.add('active'); - } - } - } - Forms.validateField(target); - } - }); - document.addEventListener('keyup', (e) => { - const target = e.target; - // Radio and Checkbox focus class - if (target instanceof HTMLInputElement && ['radio', 'checkbox'].includes(target.type)) { - // TAB, check if tabbing to radio or checkbox. - if (Utils.keys.TAB.includes(e.key)) { - target.classList.add('tabbed'); - target.addEventListener('blur', () => target.classList.remove('tabbed'), { - once: true - }); - } - } - }); - document - .querySelectorAll('.materialize-textarea') - .forEach((textArea) => { - Forms.InitTextarea(textArea); - }); - // File Input Path - document - .querySelectorAll('.file-field input[type="file"]') - .forEach((fileInput) => { - Forms.InitFileInputPath(fileInput); - }); - }); - } - static InitTextarea(textarea) { - // Save Data in Element - textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString()); - textarea.setAttribute('previous-length', (textarea.value || '').length.toString()); - Forms.textareaAutoResize(textarea); - textarea.addEventListener('keyup', (e) => Forms.textareaAutoResize(e.target)); - textarea.addEventListener('keydown', (e) => Forms.textareaAutoResize(e.target)); - } - static InitFileInputPath(fileInput) { - fileInput.addEventListener('change', () => { - const fileField = fileInput.closest('.file-field'); - const pathInput = fileField.querySelector('input.file-path'); - const files = fileInput.files; - const filenames = []; - for (let i = 0; i < files.length; i++) { - filenames.push(files[i].name); - } - pathInput.value = filenames.join(', '); - pathInput.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); - }); - } -} - -const _defaults$d = { - inDuration: 275, - outDuration: 200, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null -}; -class Materialbox extends Component { - /** If the materialbox overlay is showing. */ - overlayActive; - /** If the materialbox is no longer being animated. */ - doneAnimating; - /** Caption, if specified. */ - caption; - /** Original width of image. */ - originalWidth; - /** Original height of image. */ - originalHeight; - originInlineStyles; - placeholder; - _changedAncestorList; - newHeight; - newWidth; - windowWidth; - windowHeight; - attrWidth; - attrHeight; - _overlay; - _photoCaption; - constructor(el, options) { - super(el, options, Materialbox); - this.el['M_Materialbox'] = this; - this.options = { - ...Materialbox.defaults, - ...options - }; - this.overlayActive = false; - this.doneAnimating = true; - this.placeholder = document.createElement('div'); - this.placeholder.classList.add('material-placeholder'); - this.originalWidth = 0; - this.originalHeight = 0; - this.originInlineStyles = this.el.getAttribute('style'); - this.caption = this.el.getAttribute('data-caption') || ''; - this.el.tabIndex = 0; - // Wrap - this.el.before(this.placeholder); - this.placeholder.append(this.el); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$d; - } - /** - * Initializes instances of MaterialBox. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Materialbox); - } - static getInstance(el) { - return el['M_Materialbox']; - } - destroy() { - this._removeEventHandlers(); - this.el['M_Materialbox'] = undefined; - // Unwrap image - //this.placeholder.after(this.el).remove(); - this.placeholder.remove(); - this.el.removeAttribute('style'); - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleMaterialboxClick); - this.el.addEventListener('keypress', this._handleMaterialboxKeypress); - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleMaterialboxClick); - this.el.removeEventListener('keypress', this._handleMaterialboxKeypress); - } - _handleMaterialboxClick = () => { - this._handleMaterialboxToggle(); - }; - _handleMaterialboxKeypress = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleMaterialboxToggle(); - } - }; - _handleMaterialboxToggle = () => { - // If already modal, return to original - if (this.doneAnimating === false || (this.overlayActive && this.doneAnimating)) - this.close(); - else - this.open(); - }; - _handleWindowScroll = () => { - if (this.overlayActive) - this.close(); - }; - _handleWindowResize = () => { - if (this.overlayActive) - this.close(); - }; - _handleWindowEscape = (e) => { - if (Utils.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive) - this.close(); - }; - _makeAncestorsOverflowVisible() { - this._changedAncestorList = []; - let ancestor = this.placeholder.parentNode; - while (ancestor !== null && ancestor !== document) { - const curr = ancestor; - if (curr.style.overflow !== 'visible') { - curr.style.overflow = 'visible'; - this._changedAncestorList.push(curr); - } - ancestor = ancestor.parentNode; - } - } - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.scrollY - docElem.clientTop, - left: box.left + window.scrollX - docElem.clientLeft - }; - } - _updateVars() { - this.windowWidth = window.innerWidth; - this.windowHeight = window.innerHeight; - this.caption = this.el.getAttribute('data-caption') || ''; - } - // Image - _animateImageIn() { - this.el.style.maxHeight = this.newHeight.toString() + 'px'; - this.el.style.maxWidth = this.newWidth.toString() + 'px'; - const duration = this.options.inDuration; - // from - this.el.style.transition = 'none'; - this.el.style.height = this.originalHeight + 'px'; - this.el.style.width = this.originalWidth + 'px'; - setTimeout(() => { - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.newHeight + 'px'; - this.el.style.width = this.newWidth + 'px'; - this.el.style.left = - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2 + - 'px'; - this.el.style.top = - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2 + - 'px'; - }, 1); - setTimeout(() => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') - this.options.onOpenEnd.call(this, this.el); - }, duration); - /* - anim({ - targets: this.el, // image - height: [this.originalHeight, this.newHeight], - width: [this.originalWidth, this.newWidth], - left: - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2, - top: - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2, - - duration: this.options.inDuration, - easing: 'easeOutQuad', - complete: () => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el); - } - }); - */ - } - _animateImageOut() { - const duration = this.options.outDuration; - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.originalWidth + 'px'; - this.el.style.width = this.originalWidth + 'px'; - this.el.style.left = '0'; - this.el.style.top = '0'; - setTimeout(() => { - this.placeholder.style.height = ''; - this.placeholder.style.width = ''; - this.placeholder.style.position = ''; - this.placeholder.style.top = ''; - this.placeholder.style.left = ''; - // Revert to width or height attribute - if (this.attrWidth) - this.el.setAttribute('width', this.attrWidth.toString()); - if (this.attrHeight) - this.el.setAttribute('height', this.attrHeight.toString()); - this.el.removeAttribute('style'); - if (this.originInlineStyles) - this.el.setAttribute('style', this.originInlineStyles); - // Remove class - this.el.classList.remove('active'); - this.doneAnimating = true; - // Remove overflow overrides on ancestors - this._changedAncestorList.forEach((anchestor) => (anchestor.style.overflow = '')); - // onCloseEnd callback - if (typeof this.options.onCloseEnd === 'function') - this.options.onCloseEnd.call(this, this.el); - }, duration); - } - // Caption - _addCaption() { - this._photoCaption = document.createElement('div'); - this._photoCaption.classList.add('materialbox-caption'); - this._photoCaption.innerText = this.caption; - document.body.append(this._photoCaption); - this._photoCaption.style.display = 'inline'; - // Animate - this._photoCaption.style.transition = 'none'; - this._photoCaption.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '1'; - }, 1); - } - _removeCaption() { - const duration = this.options.outDuration; - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '0'; - setTimeout(() => { - this._photoCaption.remove(); - }, duration); - } - // Overlay - _addOverlay() { - this._overlay = document.createElement('div'); - this._overlay.id = 'materialbox-overlay'; - this._overlay.addEventListener('click', () => { - if (this.doneAnimating) - this.close(); - }, { once: true }); - // Put before in origin image to preserve z-index layering. - this.el.before(this._overlay); - // Set dimensions if needed - const overlayOffset = this._overlay.getBoundingClientRect(); - this._overlay.style.width = this.windowWidth + 'px'; - this._overlay.style.height = this.windowHeight + 'px'; - this._overlay.style.left = -1 * overlayOffset.left + 'px'; - this._overlay.style.top = -1 * overlayOffset.top + 'px'; - // Animate - this._overlay.style.transition = 'none'; - this._overlay.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '1'; - }, 1); - } - _removeOverlay() { - const duration = this.options.outDuration; - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '0'; - setTimeout(() => { - this.overlayActive = false; - this._overlay.remove(); - }, duration); - } - /** - * Open materialbox. - */ - open = () => { - this._updateVars(); - this.originalWidth = this.el.getBoundingClientRect().width; - this.originalHeight = this.el.getBoundingClientRect().height; - // Set states - this.doneAnimating = false; - this.el.classList.add('active'); - this.overlayActive = true; - // onOpenStart callback - if (typeof this.options.onOpenStart === 'function') - this.options.onOpenStart.call(this, this.el); - // Set positioning for placeholder - this.placeholder.style.width = this.placeholder.getBoundingClientRect().width + 'px'; - this.placeholder.style.height = this.placeholder.getBoundingClientRect().height + 'px'; - this.placeholder.style.position = 'relative'; - this.placeholder.style.top = '0'; - this.placeholder.style.left = '0'; - this._makeAncestorsOverflowVisible(); - // Set css on origin - this.el.style.position = 'absolute'; - this.el.style.zIndex = '1000'; - this.el.style.willChange = 'left, top, width, height'; - // Change from width or height attribute to css - this.attrWidth = this.el.getAttribute('width'); - this.attrHeight = this.el.getAttribute('height'); - if (this.attrWidth) { - this.el.style.width = this.attrWidth + 'px'; - this.el.removeAttribute('width'); - } - if (this.attrHeight) { - this.el.style.width = this.attrHeight + 'px'; - this.el.removeAttribute('height'); - } - this._addOverlay(); - // Add and animate caption if it exists - if (this.caption !== '') - this._addCaption(); - // Resize Image - const widthPercent = this.originalWidth / this.windowWidth; - const heightPercent = this.originalHeight / this.windowHeight; - this.newWidth = 0; - this.newHeight = 0; - if (widthPercent > heightPercent) { - // Width first - const ratio = this.originalHeight / this.originalWidth; - this.newWidth = this.windowWidth * 0.9; - this.newHeight = this.windowWidth * 0.9 * ratio; - } - else { - // Height first - const ratio = this.originalWidth / this.originalHeight; - this.newWidth = this.windowHeight * 0.9 * ratio; - this.newHeight = this.windowHeight * 0.9; - } - this._animateImageIn(); - // Handle Exit triggers - window.addEventListener('scroll', this._handleWindowScroll); - window.addEventListener('resize', this._handleWindowResize); - window.addEventListener('keyup', this._handleWindowEscape); - }; - /** - * Close materialbox. - */ - close = () => { - this._updateVars(); - this.doneAnimating = false; - // onCloseStart callback - if (typeof this.options.onCloseStart === 'function') - this.options.onCloseStart.call(this, this.el); - //anim.remove(this.el); - //anim.remove(this._overlay); - //if (this.caption !== '') anim.remove(this._photoCaption); - // disable exit handlers - window.removeEventListener('scroll', this._handleWindowScroll); - window.removeEventListener('resize', this._handleWindowResize); - window.removeEventListener('keyup', this._handleWindowEscape); - this._removeOverlay(); - this._animateImageOut(); - if (this.caption !== '') - this._removeCaption(); - }; -} - -const _defaults$c = { - opacity: 0.5, - inDuration: 250, - outDuration: 250, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - preventScrolling: true, - dismissible: true, - startingTop: '4%', - endingTop: '10%' -}; -class Modal extends Component { - constructor(el, options) { - super(el, options, Modal); - this.el['M_Modal'] = this; - this.options = { - ...Modal.defaults, - ...options - }; - this.el.tabIndex = 0; - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$c; - } - static init(els, options = {}) { - return super.init(els, options, Modal); - } - static getInstance(el) { - return el['M_Modal']; - } - destroy() { } - _setupEventHandlers() { } - _removeEventHandlers() { } - _handleTriggerClick() { } - _handleOverlayClick() { } - _handleModalCloseClick() { } - _handleKeydown() { } - _handleFocus() { } - open() { - return this; - } - close() { - return this; - } - // Experimental! - static #createHtml(config) { - return ` - ${config.header ? '' : ''} - - ${config.header ? '' : ''} - `; - } - static #createHtmlElement(config) { - const dialog = document.createElement('dialog'); - dialog.id = config.id; - return dialog; - } - static create(config) { - return this.#createHtmlElement(config); - } - static { } -} - -const _defaults$b = { - edge: 'left', - draggable: true, - dragTargetWidth: '10px', - inDuration: 250, - outDuration: 200, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null, - preventScrolling: true -}; -class Sidenav extends Component { - id; - /** Describes open/close state of Sidenav. */ - isOpen; - /** Describes if sidenav is fixed. */ - isFixed; - /** Describes if Sidenav is being dragged. */ - isDragged; - lastWindowWidth; - lastWindowHeight; - static _sidenavs; - _overlay; - dragTarget; - _startingXpos; - _xPos; - _time; - _width; - _initialScrollTop; - _verticallyScrolling; - deltaX; - velocityX; - percentOpen; - constructor(el, options) { - super(el, options, Sidenav); - this.el['M_Sidenav'] = this; - this.options = { - ...Sidenav.defaults, - ...options - }; - this.id = this.el.id; - this.isOpen = false; - this.isFixed = this.el.classList.contains('sidenav-fixed'); - this.isDragged = false; - // Window size variables for window resize checks - this.lastWindowWidth = window.innerWidth; - this.lastWindowHeight = window.innerHeight; - this._createOverlay(); - this._createDragTarget(); - this._setupEventHandlers(); - this._setupClasses(); - this._setupFixed(); - Sidenav._sidenavs.push(this); - } - static get defaults() { - return _defaults$b; - } - /** - * Initializes instances of Sidenav. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Sidenav); - } - static getInstance(el) { - return el['M_Sidenav']; - } - destroy() { - this._removeEventHandlers(); - this._enableBodyScrolling(); - this._overlay.parentNode.removeChild(this._overlay); - this.dragTarget.parentNode.removeChild(this.dragTarget); - this.el['M_Sidenav'] = undefined; - this.el.style.transform = ''; - const index = Sidenav._sidenavs.indexOf(this); - if (index >= 0) { - Sidenav._sidenavs.splice(index, 1); - } - } - _createOverlay() { - this._overlay = document.createElement('div'); - this._overlay.classList.add('sidenav-overlay'); - this._overlay.addEventListener('click', this.close); - document.body.appendChild(this._overlay); - } - _setupEventHandlers() { - if (Sidenav._sidenavs.length === 0) { - document.body.addEventListener('click', this._handleTriggerClick); - } - const passiveIfSupported = null; - this.dragTarget.addEventListener('touchmove', this._handleDragTargetDrag, passiveIfSupported); - this.dragTarget.addEventListener('touchend', this._handleDragTargetRelease); - this._overlay.addEventListener('touchmove', this._handleCloseDrag, passiveIfSupported); - this._overlay.addEventListener('touchend', this._handleCloseRelease); - this.el.addEventListener('touchmove', this._handleCloseDrag); // , passiveIfSupported); - this.el.addEventListener('touchend', this._handleCloseRelease); - this.el.addEventListener('click', this._handleCloseTriggerClick); - // Add resize for side nav fixed - if (this.isFixed) { - window.addEventListener('resize', this._handleWindowResize); - } - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - _removeEventHandlers() { - if (Sidenav._sidenavs.length === 1) { - document.body.removeEventListener('click', this._handleTriggerClick); - } - this.dragTarget.removeEventListener('touchmove', this._handleDragTargetDrag); - this.dragTarget.removeEventListener('touchend', this._handleDragTargetRelease); - this._overlay.removeEventListener('touchmove', this._handleCloseDrag); - this._overlay.removeEventListener('touchend', this._handleCloseRelease); - this.el.removeEventListener('touchmove', this._handleCloseDrag); - this.el.removeEventListener('touchend', this._handleCloseRelease); - this.el.removeEventListener('click', this._handleCloseTriggerClick); - // Remove resize for side nav fixed - if (this.isFixed) { - window.removeEventListener('resize', this._handleWindowResize); - } - } - _handleTriggerClick(e) { - const trigger = e.target.closest('.sidenav-trigger'); - if (e.target && trigger) { - const sidenavId = Utils.getIdFromTrigger(trigger); - const sidenavInstance = document.getElementById(sidenavId)['M_Sidenav']; - if (sidenavInstance) { - sidenavInstance.open(); - } - e.preventDefault(); - } - } - // Set variables needed at the beginning of drag and stop any current transition. - _startDrag(e) { - const clientX = e.targetTouches[0].clientX; - this.isDragged = true; - this._startingXpos = clientX; - this._xPos = this._startingXpos; - this._time = Date.now(); - this._width = this.el.getBoundingClientRect().width; - this._overlay.style.display = 'block'; - this._initialScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop(); - this._verticallyScrolling = false; - } - //Set variables needed at each drag move update tick - _dragMoveUpdate(e) { - const clientX = e.targetTouches[0].clientX; - const currentScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop(); - this.deltaX = Math.abs(this._xPos - clientX); - this._xPos = clientX; - this.velocityX = this.deltaX / (Date.now() - this._time); - this._time = Date.now(); - if (this._initialScrollTop !== currentScrollTop) { - this._verticallyScrolling = true; - } - } - _handleDragTargetDrag = (e) => { - // Check if draggable - if (!this._isDraggable()) - return; - let totalDeltaX = this._calculateDelta(e); - const dragDirection = totalDeltaX > 0 ? 'right' : 'left'; - // Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction - totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX)); - if (this.options.edge === dragDirection) { - totalDeltaX = 0; - } - /** - * transformX is the drag displacement - * transformPrefix is the initial transform placement - * Invert values if Sidenav is right edge - */ - let transformX = totalDeltaX; - let transformPrefix = 'translateX(-100%)'; - if (this.options.edge === 'right') { - transformPrefix = 'translateX(100%)'; - transformX = -transformX; - } - // Calculate open/close percentage of sidenav, with open = 1 and close = 0 - this.percentOpen = Math.min(1, totalDeltaX / this._width); - // Set transform and opacity styles - this.el.style.transform = `${transformPrefix} translateX(${transformX}px)`; - this._overlay.style.opacity = this.percentOpen.toString(); - }; - _handleDragTargetRelease = () => { - if (this.isDragged) { - if (this.percentOpen > 0.2) { - this.open(); - } - else { - this._animateOut(); - } - this.isDragged = false; - this._verticallyScrolling = false; - } - }; - _handleCloseDrag = (e) => { - // Check if open and draggable - if (!this.isOpen || !this._isDraggable()) - return; - let totalDeltaX = this._calculateDelta(e); - // dragDirection is the attempted user drag direction - const dragDirection = totalDeltaX > 0 ? 'right' : 'left'; - totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX)); - if (this.options.edge !== dragDirection) { - totalDeltaX = 0; - } - let transformX = -totalDeltaX; - if (this.options.edge === 'right') { - transformX = -transformX; - } - // Calculate open/close percentage of sidenav, with open = 1 and close = 0 - this.percentOpen = Math.min(1, 1 - totalDeltaX / this._width); - // Set transform and opacity styles - this.el.style.transform = `translateX(${transformX}px)`; - this._overlay.style.opacity = this.percentOpen.toString(); - }; - _calculateDelta = (e) => { - // If not being dragged, set initial drag start variables - if (!this.isDragged) { - this._startDrag(e); - } - // Run touchmove updates - this._dragMoveUpdate(e); - // Calculate raw deltaX - return this._xPos - this._startingXpos; - }; - _handleCloseRelease = () => { - if (this.isOpen && this.isDragged) { - if (this.percentOpen > 0.8) { - this._animateIn(); - } - else { - this.close(); - } - this.isDragged = false; - this._verticallyScrolling = false; - } - }; - // Handles closing of Sidenav when element with class .sidenav-close - _handleCloseTriggerClick = (e) => { - const closeTrigger = e.target.closest('.sidenav-close'); - if (closeTrigger && !this._isCurrentlyFixed()) { - this.close(); - } - }; - _handleWindowResize = () => { - // Only handle horizontal resizes - if (this.lastWindowWidth !== window.innerWidth) { - if (window.innerWidth > 992) { - this.open(); - } - else { - this.close(); - } - } - this.lastWindowWidth = window.innerWidth; - this.lastWindowHeight = window.innerHeight; - }; - _setupClasses() { - if (this.options.edge === 'right') { - this.el.classList.add('right-aligned'); - this.dragTarget.classList.add('right-aligned'); - } - } - _removeClasses() { - this.el.classList.remove('right-aligned'); - this.dragTarget.classList.remove('right-aligned'); - } - _setupFixed() { - if (this._isCurrentlyFixed()) - this.open(); - } - _isDraggable() { - return this.options.draggable && !this._isCurrentlyFixed() && !this._verticallyScrolling; - } - _isCurrentlyFixed() { - return this.isFixed && window.innerWidth > 992; - } - _createDragTarget() { - const dragTarget = document.createElement('div'); - dragTarget.classList.add('drag-target'); - dragTarget.style.width = this.options.dragTargetWidth; - document.body.appendChild(dragTarget); - this.dragTarget = dragTarget; - } - _preventBodyScrolling() { - document.body.style.overflow = 'hidden'; - } - _enableBodyScrolling() { - document.body.style.overflow = ''; - } - /** - * Opens Sidenav. - */ - open = () => { - if (this.isOpen === true) - return; - this.isOpen = true; - // Run onOpenStart callback - if (typeof this.options.onOpenStart === 'function') { - this.options.onOpenStart.call(this, this.el); - } - // Handle fixed Sidenav - if (this._isCurrentlyFixed()) { - // Show if fixed - this.el.style.transform = 'translateX(0)'; - this._enableBodyScrolling(); - this._overlay.style.display = 'none'; - } - // Handle non-fixed Sidenav - else { - if (this.options.preventScrolling) - this._preventBodyScrolling(); - if (!this.isDragged || this.percentOpen != 1) - this._animateIn(); - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - }; - /** - * Closes Sidenav. - */ - close = () => { - if (this.isOpen === false) - return; - this.isOpen = false; - // Run onCloseStart callback - if (typeof this.options.onCloseStart === 'function') { - this.options.onCloseStart.call(this, this.el); - } - // Handle fixed Sidenav - if (this._isCurrentlyFixed()) { - const transformX = this.options.edge === 'left' ? '-105%' : '105%'; - this.el.style.transform = `translateX(${transformX})`; - } - // Handle non-fixed Sidenav - else { - this._enableBodyScrolling(); - if (!this.isDragged || this.percentOpen != 0) { - this._animateOut(); - } - else { - this._overlay.style.display = 'none'; - } - /* Set aria-hidden state */ - this._setAriaHidden(); - this._setTabIndex(); - } - }; - _animateIn() { - this._animateSidenavIn(); - this._animateOverlayIn(); - } - _animateOut() { - this._animateSidenavOut(); - this._animateOverlayOut(); - } - _animateSidenavIn() { - let slideOutPercent = this.options.edge === 'left' ? -1 : 1; - if (this.isDragged) { - slideOutPercent = - this.options.edge === 'left' - ? slideOutPercent + this.percentOpen - : slideOutPercent - this.percentOpen; - } - const duration = this.options.inDuration; - // from - this.el.style.transition = 'none'; - this.el.style.transform = 'translateX(' + slideOutPercent * 100 + '%)'; - setTimeout(() => { - this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad - // to - this.el.style.transform = 'translateX(0)'; - }, 1); - setTimeout(() => { - if (typeof this.options.onOpenEnd === 'function') - this.options.onOpenEnd.call(this, this.el); - }, duration); - } - _animateSidenavOut() { - const endPercent = this.options.edge === 'left' ? -1 : 1; - // let slideOutPercent = 0; - // if (this.isDragged) { - // // @todo unused variable - // slideOutPercent = - // this.options.edge === 'left' - // ? endPercent + this.percentOpen - // : endPercent - this.percentOpen; - // } - const duration = this.options.outDuration; - this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad - // to - this.el.style.transform = 'translateX(' + endPercent * 100 + '%)'; - setTimeout(() => { - if (typeof this.options.onCloseEnd === 'function') - this.options.onCloseEnd.call(this, this.el); - }, duration); - } - _animateOverlayIn() { - let start = 0; - if (this.isDragged) - start = this.percentOpen; - else - this._overlay.style.display = 'block'; - // Animation - const duration = this.options.inDuration; - // from - this._overlay.style.transition = 'none'; - this._overlay.style.opacity = start.toString(); - // easeOutQuad - setTimeout(() => { - this._overlay.style.transition = `opacity ${duration}ms ease`; - // to - this._overlay.style.opacity = '1'; - }, 1); - } - _animateOverlayOut() { - const duration = this.options.outDuration; - // easeOutQuad - this._overlay.style.transition = `opacity ${duration}ms ease`; - // to - this._overlay.style.opacity = '0'; - setTimeout(() => { - this._overlay.style.display = 'none'; - }, duration); - } - _setAriaHidden = () => { - this.el.ariaHidden = this.isOpen ? 'false' : 'true'; - const navWrapper = document.querySelector('.nav-wrapper ul'); - if (navWrapper) - navWrapper.ariaHidden = this.isOpen.toString(); - }; - _setTabIndex = () => { - const navLinks = document.querySelectorAll('.nav-wrapper ul li a'); - const sideNavLinks = document.querySelectorAll('.sidenav li a'); - if (navLinks) - navLinks.forEach((navLink) => { - navLink.tabIndex = this.isOpen ? -1 : 0; - }); - if (sideNavLinks) - sideNavLinks.forEach((sideNavLink) => { - sideNavLink.tabIndex = this.isOpen ? 0 : -1; - }); - }; - static { - Sidenav._sidenavs = []; - } -} - -const _defaults$a = { - indicators: true, - height: 400, - duration: 500, - interval: 6000, - pauseOnFocus: true, - pauseOnHover: true, - indicatorLabelFunc: null // Function which will generate a label for the indicators (ARIA) -}; -class Slider extends Component { - /** Index of current slide. */ - activeIndex; - interval; - eventPause; - _slider; - _slides; - _activeSlide; - _indicators; - _hovered; - _focused; - _focusCurrent; - _sliderId; - constructor(el, options) { - super(el, options, Slider); - this.el['M_Slider'] = this; - this.options = { - ...Slider.defaults, - ...options - }; - // init props - this.interval = null; - this.eventPause = false; - this._hovered = false; - this._focused = false; - this._focusCurrent = false; - // setup - this._slider = this.el.querySelector('.slides'); - this._slides = Array.from(this._slider.querySelectorAll('li')); - this.activeIndex = this._slides.findIndex((li) => li.classList.contains('active')); - if (this.activeIndex !== -1) { - this._activeSlide = this._slides[this.activeIndex]; - } - this._setSliderHeight(); - // Sets element id if it does not have one - if (this._slider.hasAttribute('id')) - this._sliderId = this._slider.getAttribute('id'); - else { - this._sliderId = 'slider-' + Utils.guid(); - this._slider.setAttribute('id', this._sliderId); - } - const placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; - // Set initial positions of captions - this._slides.forEach((slide) => { - // Caption - //const caption = slide.querySelector('.caption'); - //if (caption) this._animateCaptionIn(caption, 0); - // Set Images as Background Images - const img = slide.querySelector('img'); - if (img) { - if (img.src !== placeholderBase64) { - img.style.backgroundImage = 'url(' + img.src + ')'; - img.src = placeholderBase64; - } - } - // Sets slide as focusable by code - if (!slide.hasAttribute('tabindex')) - slide.setAttribute('tabindex', '-1'); - // Removes initial visibility from "inactive" slides - slide.style.visibility = 'hidden'; - }); - this._setupIndicators(); - // Show active slide - if (this._activeSlide) { - this._activeSlide.style.display = 'block'; - this._activeSlide.style.visibility = 'visible'; - } - else { - this.activeIndex = 0; - this._slides[0].classList.add('active'); - this._slides[0].style.visibility = 'visible'; - this._activeSlide = this._slides[0]; - this._animateSlide(this._slides[0], true); - // Update indicators - if (this.options.indicators) { - this._indicators[this.activeIndex].children[0].classList.add('active'); - } - } - this._setupEventHandlers(); - // auto scroll - this.start(); - } - static get defaults() { - return _defaults$a; - } - /** - * Initializes instances of Slider. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Slider); - } - static getInstance(el) { - return el['M_Slider']; - } - destroy() { - this.pause(); - this._removeIndicators(); - this._removeEventHandlers(); - this.el['M_Slider'] = undefined; - } - _setupEventHandlers() { - if (this.options.pauseOnFocus) { - this.el.addEventListener('focusin', this._handleAutoPauseFocus); - this.el.addEventListener('focusout', this._handleAutoStartFocus); - } - if (this.options.pauseOnHover) { - this.el.addEventListener('mouseenter', this._handleAutoPauseHover); - this.el.addEventListener('mouseleave', this._handleAutoStartHover); - } - if (this.options.indicators) { - this._indicators.forEach((el) => { - el.addEventListener('click', this._handleIndicatorClick); - }); - } - } - _removeEventHandlers() { - if (this.options.pauseOnFocus) { - this.el.removeEventListener('focusin', this._handleAutoPauseFocus); - this.el.removeEventListener('focusout', this._handleAutoStartFocus); - } - if (this.options.pauseOnHover) { - this.el.removeEventListener('mouseenter', this._handleAutoPauseHover); - this.el.removeEventListener('mouseleave', this._handleAutoStartHover); - } - if (this.options.indicators) { - this._indicators.forEach((el) => { - el.removeEventListener('click', this._handleIndicatorClick); - }); - } - } - _handleIndicatorClick = (e) => { - const el = e.target.parentElement; - const currIndex = [...el.parentNode.children].indexOf(el); - this._focusCurrent = true; - this.set(currIndex); - }; - _handleAutoPauseHover = () => { - this._hovered = true; - if (this.interval != null) { - this._pause(true); - } - }; - _handleAutoPauseFocus = () => { - this._focused = true; - if (this.interval != null) { - this._pause(true); - } - }; - _handleAutoStartHover = () => { - this._hovered = false; - if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) { - this.start(); - } - }; - _handleAutoStartFocus = () => { - this._focused = false; - if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) { - this.start(); - } - }; - _handleInterval = () => { - const activeElem = this._slider.querySelector('.active'); - let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem); - if (this._slides.length === newActiveIndex + 1) - newActiveIndex = 0; // loop to start - else - newActiveIndex += 1; - this.set(newActiveIndex); - }; - _animateSlide(slide, isDirectionIn) { - let dx = 0, dy = 0; - // from - slide.style.opacity = isDirectionIn ? '0' : '1'; - setTimeout(() => { - slide.style.transition = `opacity ${this.options.duration}ms ease`; - // to - slide.style.opacity = isDirectionIn ? '1' : '0'; - }, 1); - // Caption - const caption = slide.querySelector('.caption'); - if (!caption) - return; - if (caption.classList.contains('center-align')) - dy = -100; - else if (caption.classList.contains('right-align')) - dx = 100; - else if (caption.classList.contains('left-align')) - dx = -100; - // from - caption.style.opacity = isDirectionIn ? '0' : '1'; - caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`; - setTimeout(() => { - caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`; - // to - caption.style.opacity = isDirectionIn ? '1' : '0'; - caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`; - }, this.options.duration); // delay - } - _setSliderHeight() { - // If fullscreen, do nothing - if (!this.el.classList.contains('fullscreen')) { - if (this.options.indicators) { - // Add height if indicators are present - this.el.style.height = this.options.height + 40 + 'px'; //.css('height', this.options.height + 40 + 'px'); - } - else { - this.el.style.height = this.options.height + 'px'; - } - this._slider.style.height = this.options.height + 'px'; - } - } - _setupIndicators() { - if (this.options.indicators) { - const ul = document.createElement('ul'); - ul.classList.add('indicators'); - const arrLi = []; - this._slides.forEach((el, i) => { - const label = this.options.indicatorLabelFunc - ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0) - : `${i + 1}`; - const li = document.createElement('li'); - li.classList.add('indicator-item'); - li.innerHTML = ``; - arrLi.push(li); - ul.append(li); - }); - this.el.append(ul); - this._indicators = arrLi; - } - } - _removeIndicators() { - this.el.querySelector('ul.indicators').remove(); //find('ul.indicators').remove(); - } - set(index) { - // Wrap around indices. - if (index >= this._slides.length) - index = 0; - else if (index < 0) - index = this._slides.length - 1; - // Only do if index changes - if (this.activeIndex === index) - return; - this._activeSlide = this._slides[this.activeIndex]; - const _caption = this._activeSlide.querySelector('.caption'); - this._activeSlide.classList.remove('active'); - // Enables every slide - this._slides.forEach((slide) => (slide.style.visibility = 'visible')); - //--- Hide active Slide + Caption - this._activeSlide.style.opacity = '0'; - setTimeout(() => { - this._slides.forEach((slide) => { - if (slide.classList.contains('active')) - return; - slide.style.opacity = '0'; - slide.style.transform = 'translate(0, 0)'; - // Disables invisible slides (for assistive technologies) - slide.style.visibility = 'hidden'; - }); - }, this.options.duration); - // Hide active Caption - //this._animateCaptionIn(_caption, this.options.duration); - _caption.style.opacity = '0'; - // Update indicators - if (this.options.indicators) { - const activeIndicator = this._indicators[this.activeIndex].children[0]; - const nextIndicator = this._indicators[index].children[0]; - activeIndicator.classList.remove('active'); - nextIndicator.classList.add('active'); - if (typeof this.options.indicatorLabelFunc === 'function') { - activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, this.activeIndex, false); - nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true); - } - } - //--- Show new Slide + Caption - this._animateSlide(this._slides[index], true); - this._slides[index].classList.add('active'); - this.activeIndex = index; - // Reset interval, if allowed. This check prevents autostart - // when slider is paused, since it can be changed though indicators. - if (this.interval != null) { - this.start(); - } - } - _pause(fromEvent) { - clearInterval(this.interval); - this.eventPause = fromEvent; - this.interval = null; - } - /** - * Pause slider autoslide. - */ - pause = () => { - this._pause(false); - }; - /** - * Start slider autoslide. - */ - start = () => { - clearInterval(this.interval); - this.interval = setInterval(this._handleInterval, this.options.duration + this.options.interval); - this.eventPause = false; - }; - /** - * Move to next slider. - */ - next = () => { - let newIndex = this.activeIndex + 1; - // Wrap around indices. - if (newIndex >= this._slides.length) - newIndex = 0; - else if (newIndex < 0) - newIndex = this._slides.length - 1; - this.set(newIndex); - }; - /** - * Move to prev slider. - */ - prev = () => { - let newIndex = this.activeIndex - 1; - // Wrap around indices. - if (newIndex >= this._slides.length) - newIndex = 0; - else if (newIndex < 0) - newIndex = this._slides.length - 1; - this.set(newIndex); - }; -} - -const _defaults$9 = { - duration: 300, - onShow: null, - swipeable: false, - responsiveThreshold: Infinity // breakpoint for swipeable -}; -class Tabs extends Component { - _tabLinks; - _index; - _indicator; - _tabWidth; - _tabsWidth; - _tabsCarousel; - _activeTabLink; - _content; - constructor(el, options) { - super(el, options, Tabs); - this.el['M_Tabs'] = this; - this.options = { - ...Tabs.defaults, - ...options - }; - this._tabLinks = this.el.querySelectorAll('li.tab > a'); - this._index = 0; - this._setupActiveTabLink(); - if (this.options.swipeable) { - this._setupSwipeableTabs(); - } - else { - this._setupNormalTabs(); - } - // Setup tabs indicator after content to ensure accurate widths - this._setTabsAndTabWidth(); - this._createIndicator(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$9; - } - /** - * Initializes instances of Tabs. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Tabs); - } - static getInstance(el) { - return el['M_Tabs']; - } - destroy() { - this._removeEventHandlers(); - this._indicator.parentNode.removeChild(this._indicator); - if (this.options.swipeable) { - this._teardownSwipeableTabs(); - } - else { - this._teardownNormalTabs(); - } - this.el['M_Tabs'] = undefined; - } - /** - * The index of tab that is currently shown. - */ - get index() { - return this._index; - } - _setupEventHandlers() { - window.addEventListener('resize', this._handleWindowResize); - this.el.addEventListener('click', this._handleTabClick); - // map vertical scrolling to horizontal scrolling because no scrollbar is shown on desktop - this.el.addEventListener('wheel', (event) => { - if (event.deltaY !== 0) { - event.preventDefault(); - this.el.scrollLeft += event.deltaY * 1; - } - }); - } - _removeEventHandlers() { - window.removeEventListener('resize', this._handleWindowResize); - this.el.removeEventListener('click', this._handleTabClick); - } - _handleWindowResize = () => { - this._setTabsAndTabWidth(); - if (this._tabWidth !== 0 && this._tabsWidth !== 0) { - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - }; - _handleTabClick = (e) => { - let tabLink = e.target; - if (!tabLink) - return; - let tab = tabLink.parentElement; - while (tab && !tab.classList.contains('tab')) { - tabLink = tabLink.parentElement; - tab = tab.parentElement; - } - // Handle click on tab link only - if (!tabLink || !tab.classList.contains('tab')) - return; - // is disabled? - if (tab.classList.contains('disabled')) { - e.preventDefault(); - return; - } - // Act as regular link if target attribute is specified. - if (tabLink.hasAttribute('target')) - return; - // Make the old tab inactive. - this._activeTabLink.classList.remove('active'); - const _oldContent = this._content; - // Update the variables with the new link and content - this._activeTabLink = tabLink; - if (tabLink.hash) - this._content = document.querySelector(tabLink.hash); - this._tabLinks = this.el.querySelectorAll('li.tab > a'); - // Make the tab active - this._activeTabLink.classList.add('active'); - const prevIndex = this._index; - this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0); - // Swap content - if (this.options.swipeable) { - if (this._tabsCarousel) { - this._tabsCarousel.set(this._index, () => { - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - }); - } - } - else { - if (this._content) { - this._content.style.display = 'block'; - this._content.classList.add('active'); - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - if (_oldContent && _oldContent !== this._content) { - _oldContent.style.display = 'none'; - _oldContent.classList.remove('active'); - } - } - } - // Update widths after content is swapped (scrollbar bugfix) - this._setTabsAndTabWidth(); - this._animateIndicator(prevIndex); - e.preventDefault(); - }; - _createIndicator() { - const indicator = document.createElement('li'); - indicator.classList.add('indicator'); - this.el.appendChild(indicator); - this._indicator = indicator; - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - _setupActiveTabLink() { - // If the location.hash matches one of the links, use that as the active tab. - this._activeTabLink = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === location.hash); - // If no match is found, use the first link or any with class 'active' as the initial active tab. - if (!this._activeTabLink) { - let activeTabLink = this.el.querySelector('li.tab a.active'); - if (!activeTabLink) { - activeTabLink = this.el.querySelector('li.tab a'); - } - this._activeTabLink = activeTabLink; - } - Array.from(this._tabLinks).forEach((a) => a.classList.remove('active')); - this._activeTabLink.classList.add('active'); - this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0); - if (this._activeTabLink && this._activeTabLink.hash) { - this._content = document.querySelector(this._activeTabLink.hash); - if (this._content) - this._content.classList.add('active'); - } - } - _setupSwipeableTabs() { - // Change swipeable according to responsive threshold - if (window.innerWidth > this.options.responsiveThreshold) - this.options.swipeable = false; - const tabsContent = []; - this._tabLinks.forEach((a) => { - if (a.hash) { - const currContent = document.querySelector(a.hash); - currContent.classList.add('carousel-item'); - tabsContent.push(currContent); - } - }); - // Create Carousel-Wrapper around Tab-Contents - const tabsWrapper = document.createElement('div'); - tabsWrapper.classList.add('tabs-content', 'carousel', 'carousel-slider'); - // Wrap around - tabsContent[0].parentElement.insertBefore(tabsWrapper, tabsContent[0]); - tabsContent.forEach((tabContent) => { - tabsWrapper.appendChild(tabContent); - tabContent.style.display = ''; - }); - // Keep active tab index to set initial carousel slide - const tab = this._activeTabLink.parentElement; - const activeTabIndex = Array.from(tab.parentNode.children).indexOf(tab); - this._tabsCarousel = Carousel.init(tabsWrapper, { - fullWidth: true, - noWrap: true, - onCycleTo: (item) => { - const prevIndex = this._index; - this._index = Array.from(item.parentNode.children).indexOf(item); - this._activeTabLink.classList.remove('active'); - this._activeTabLink = Array.from(this._tabLinks)[this._index]; - this._activeTabLink.classList.add('active'); - this._animateIndicator(prevIndex); - if (typeof this.options.onShow === 'function') - this.options.onShow.call(this, this._content); - } - }); - // Set initial carousel slide to active tab - this._tabsCarousel.set(activeTabIndex); - } - _teardownSwipeableTabs() { - const tabsWrapper = this._tabsCarousel.el; - this._tabsCarousel.destroy(); - // Unwrap - tabsWrapper.append(tabsWrapper.parentElement); - tabsWrapper.remove(); - } - _setupNormalTabs() { - // Hide Tabs Content - Array.from(this._tabLinks).forEach((a) => { - if (a === this._activeTabLink) - return; - if (a.hash) { - const currContent = document.querySelector(a.hash); - if (currContent) - currContent.style.display = 'none'; - } - }); - } - _teardownNormalTabs() { - // show Tabs Content - this._tabLinks.forEach((a) => { - if (a.hash) { - const currContent = document.querySelector(a.hash); - if (currContent) - currContent.style.display = ''; - } - }); - } - _setTabsAndTabWidth() { - this._tabsWidth = this.el.getBoundingClientRect().width; - this._tabWidth = Math.max(this._tabsWidth, this.el.scrollWidth) / this._tabLinks.length; - } - _calcRightPos(el) { - return Math.ceil(this._tabsWidth - el.offsetLeft - el.getBoundingClientRect().width); - } - _calcLeftPos(el) { - return Math.floor(el.offsetLeft); - } - /** - * Recalculate tab indicator position. This is useful when - * the indicator position is not correct. - */ - updateTabIndicator() { - this._setTabsAndTabWidth(); - this._animateIndicator(this._index); - } - _animateIndicator(prevIndex) { - let leftDelay = 0, rightDelay = 0; - const isMovingLeftOrStaying = this._index - prevIndex >= 0; - if (isMovingLeftOrStaying) - leftDelay = 90; - else - rightDelay = 90; - // in v1: easeOutQuad - this._indicator.style.transition = ` - left ${this.options.duration}ms ease-out ${leftDelay}ms, - right ${this.options.duration}ms ease-out ${rightDelay}ms`; - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; - } - /** - * Show tab content that corresponds to the tab with the id. - * @param tabId The id of the tab that you want to switch to. - */ - select(tabId) { - const tab = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === '#' + tabId); - if (tab) - tab.click(); - } -} - -const _defaults$8 = { - dialRadius: 135, - outerRadius: 105, - innerRadius: 70, - tickRadius: 20, - duration: 350, - container: null, - defaultTime: 'now', // default time, 'now' or '13:14' e.g. - fromNow: 0, // Millisecond offset from the defaultTime - showClearBtn: false, - autoSubmit: true, - // internationalization - i18n: { - cancel: 'Cancel', - clear: 'Clear', - done: 'Ok' - }, - twelveHour: true, // change to 12 hour AM/PM clock from 24 hour - vibrate: true, // vibrate the device when dragging clock hand - // Callbacks - onSelect: null, - onInputInteraction: null, - onDone: null, - onCancel: null, - displayPlugin: null, - displayPluginOptions: null -}; -class Timepicker extends Component { - id; - containerEl; - plate; - digitalClock; - inputHours; - inputMinutes; - x0; - y0; - moved; - dx; - dy; - /** - * Current view on the timepicker. - * @default 'hours' - */ - currentView; - hand; - minutesView; - hours; - minutes; - /** The selected time. */ - time; - /** - * If the time is AM or PM on twelve-hour clock. - * @default 'PM' - */ - amOrPm; - static _template; - /** Vibrate device when dragging clock hand. */ - vibrate; - _canvas; - hoursView; - spanAmPm; - footer; - _amBtn; - _pmBtn; - bg; - bearing; - g; - toggleViewTimer; - vibrateTimer; - displayPlugin; - constructor(el, options) { - super(el, options, Timepicker); - this.el['M_Timepicker'] = this; - this.options = { - ...Timepicker.defaults, - ...options - }; - this.id = Utils.guid(); - this._insertHTMLIntoDOM(); - this._setupVariables(); - this._setupEventHandlers(); - this._clockSetup(); - if (this.options.displayPlugin) - this._setupDisplayPlugin(); - this._pickerSetup(); - } - static get defaults() { - return _defaults$8; - } - /** - * Initializes instances of Timepicker. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Timepicker); - } - static _addLeadingZero(num) { - return (num < 10 ? '0' : '') + num; - } - static _createSVGEl(name) { - const svgNS = 'http://www.w3.org/2000/svg'; - return document.createElementNS(svgNS, name); - } - static _Pos(e) { - if (e.type.startsWith('touch') && e.targetTouches.length >= 1) { - return { - x: e.targetTouches[0].clientX, - y: e.targetTouches[0].clientY - }; - } - // mouse event - return { x: e.clientX, y: e.clientY }; - } - static getInstance(el) { - return el['M_Timepicker']; - } - destroy() { - this._removeEventHandlers(); - this.containerEl.remove(); - this.el['M_Timepicker'] = undefined; - } - _setupEventHandlers() { - this.el.addEventListener('click', this._handleInputClick); - // @todo allow input field to fill values from input field when container/modal opens - this.el.addEventListener('keydown', this._handleInputKeydown); - this.plate.addEventListener('mousedown', this._handleClockClickStart); - this.plate.addEventListener('touchstart', this._handleClockClickStart); - this.digitalClock.addEventListener('keyup', this._inputFromTextField); - this.inputHours.addEventListener('focus', () => this.showView('hours')); - this.inputHours.addEventListener('focusout', () => this.formatHours()); - this.inputMinutes.addEventListener('focus', () => this.showView('minutes')); - this.inputMinutes.addEventListener('focusout', () => this.formatMinutes()); - } - _removeEventHandlers() { - this.el.removeEventListener('click', this._handleInputClick); - this.el.removeEventListener('keydown', this._handleInputKeydown); - } - _handleInputClick = () => { - this.inputHours.focus(); - if (typeof this.options.onInputInteraction === 'function') - this.options.onInputInteraction.call(this); - if (this.displayPlugin) - this.displayPlugin.show(); - }; - _handleInputKeydown = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this.inputHours.focus(); - if (typeof this.options.onInputInteraction === 'function') - this.options.onInputInteraction.call(this); - if (this.displayPlugin) - this.displayPlugin.show(); - } - }; - _handleTimeInputEnterKey = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - e.preventDefault(); - this._inputFromTextField(); - } - }; - _handleClockClickStart = (e) => { - e.preventDefault(); - const clockPlateBR = this.plate.getBoundingClientRect(); - const offset = { x: clockPlateBR.left, y: clockPlateBR.top }; - this.x0 = offset.x + this.options.dialRadius; - this.y0 = offset.y + this.options.dialRadius; - this.moved = false; - const clickPos = Timepicker._Pos(e); - this.dx = clickPos.x - this.x0; - this.dy = clickPos.y - this.y0; - // Set clock hands - this.setHand(this.dx, this.dy, false); - // Mousemove on document - document.addEventListener('mousemove', this._handleDocumentClickMove); - document.addEventListener('touchmove', this._handleDocumentClickMove); - // Mouseup on document - document.addEventListener('mouseup', this._handleDocumentClickEnd); - document.addEventListener('touchend', this._handleDocumentClickEnd); - }; - _handleDocumentClickMove = (e) => { - e.preventDefault(); - const clickPos = Timepicker._Pos(e); - const x = clickPos.x - this.x0; - const y = clickPos.y - this.y0; - this.moved = true; - this.setHand(x, y, false); - }; - _handleDocumentClickEnd = (e) => { - e.preventDefault(); - document.removeEventListener('mouseup', this._handleDocumentClickEnd); - document.removeEventListener('touchend', this._handleDocumentClickEnd); - const clickPos = Timepicker._Pos(e); - const x = clickPos.x - this.x0; - const y = clickPos.y - this.y0; - if (this.moved && x === this.dx && y === this.dy) { - this.setHand(x, y); - } - if (this.currentView === 'hours') { - this.inputMinutes.focus(); - this.showView('minutes', this.options.duration / 2); - } - else { - // this.minutesView.classList.add('timepicker-dial-out'); - setTimeout(() => { - if (this.options.autoSubmit) - this.done(); - }, this.options.duration / 2); - } - if (typeof this.options.onSelect === 'function') { - this.options.onSelect.call(this, this.hours, this.minutes); - } - // Unbind mousemove event - document.removeEventListener('mousemove', this._handleDocumentClickMove); - document.removeEventListener('touchmove', this._handleDocumentClickMove); - }; - _insertHTMLIntoDOM() { - const template = document.createElement('template'); - template.innerHTML = Timepicker._template.trim(); - this.containerEl = template.content.firstChild; - this.containerEl.id = 'container-' + this.id; - // Append popover to input by default - const optEl = this.options.container; - const containerEl = optEl instanceof HTMLElement ? optEl : document.querySelector(optEl); - if (this.options.container && !!containerEl) { - containerEl.append(this.containerEl); - } - else { - this.el.parentElement.appendChild(this.containerEl); - } - } - _setupVariables() { - this.currentView = 'hours'; - this.vibrate = navigator.vibrate - ? 'vibrate' - : navigator['webkitVibrate'] - ? 'webkitVibrate' - : null; - this._canvas = this.containerEl.querySelector('.timepicker-canvas'); - this.plate = this.containerEl.querySelector('.timepicker-plate'); - this.digitalClock = this.containerEl.querySelector('.timepicker-display-column'); - this.hoursView = this.containerEl.querySelector('.timepicker-hours'); - this.minutesView = this.containerEl.querySelector('.timepicker-minutes'); - this.inputHours = this.containerEl.querySelector('.timepicker-input-hours'); - this.inputMinutes = this.containerEl.querySelector('.timepicker-input-minutes'); - this.spanAmPm = this.containerEl.querySelector('.timepicker-span-am-pm'); - this.footer = this.containerEl.querySelector('.timepicker-footer'); - this.amOrPm = 'PM'; - } - /*private _createButton(text: string, visibility: string): HTMLButtonElement { - const button = document.createElement('button'); - button.classList.add('btn', 'waves-effect', 'text'); - button.style.visibility = visibility; - button.type = 'button'; - button.tabIndex = -1; - button.innerText = text; - return button; - }*/ - _pickerSetup() { - // clearButton.classList.add('timepicker-clear'); - // clearButton.addEventListener('click', this.clear); - // this.footer.appendChild(clearButton); - if (this.options.showClearBtn) { - Utils.createButton(this.footer, this.options.i18n.clear, ['timepicker-clear'], true, this.clear); - } - if (!this.options.autoSubmit) { - /*const confirmationBtnsContainer = document.createElement('div'); - confirmationBtnsContainer.classList.add('confirmation-btns'); - this.footer.append(confirmationBtnsContainer); - - const cancelButton = this._createButton(this.options.i18n.cancel, ''); - cancelButton.classList.add('timepicker-close'); - cancelButton.addEventListener('click', this.close); - confirmationBtnsContainer.appendChild(cancelButton); - - const doneButton = this._createButton(this.options.i18n.done, ''); - doneButton.classList.add('timepicker-close'); - //doneButton.addEventListener('click', this._finishSelection); - confirmationBtnsContainer.appendChild(doneButton);*/ - Utils.createConfirmationContainer(this.footer, this.options.i18n.done, this.options.i18n.cancel, this.confirm, this.cancel); - } - this._updateTimeFromInput(); - this.showView('hours'); - } - _setupDisplayPlugin() { - if (this.options.displayPlugin === 'docked') - this.displayPlugin = DockedDisplayPlugin.init(this.el, this.containerEl, this.options.displayPluginOptions); - if (this.options.displayPlugin === 'modal') { - this.displayPlugin = ModalDisplayPlugin.init(this.el, this.containerEl, { - ...this.options.displayPluginOptions, - ...{ classList: ['timepicker-modal'] } - }); - this.footer.remove(); - this.footer = this.displayPlugin.footer; - } - } - _clockSetup() { - if (this.options.twelveHour) { - // AM Button - this._amBtn = document.createElement('div'); - this._amBtn.classList.add('am-btn', 'btn'); - this._amBtn.innerText = 'AM'; - this._amBtn.tabIndex = 0; - this._amBtn.addEventListener('click', this._handleAmPmClick); - this._amBtn.addEventListener('keypress', this._handleAmPmKeypress); - this.spanAmPm.appendChild(this._amBtn); - // PM Button - this._pmBtn = document.createElement('div'); - this._pmBtn.classList.add('pm-btn', 'btn'); - this._pmBtn.innerText = 'PM'; - this._pmBtn.tabIndex = 0; - this._pmBtn.addEventListener('click', this._handleAmPmClick); - this._pmBtn.addEventListener('keypress', this._handleAmPmKeypress); - this.spanAmPm.appendChild(this._pmBtn); - } - this._buildHoursView(); - this._buildMinutesView(); - this._buildSVGClock(); - } - _buildSVGClock() { - // Draw clock hands and others - const dialRadius = this.options.dialRadius; - const tickRadius = this.options.tickRadius; - const diameter = dialRadius * 2; - const svg = Timepicker._createSVGEl('svg'); - svg.setAttribute('class', 'timepicker-svg'); - svg.setAttribute('width', diameter.toString()); - svg.setAttribute('height', diameter.toString()); - const g = Timepicker._createSVGEl('g'); - g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')'); - const bearing = Timepicker._createSVGEl('circle'); - bearing.setAttribute('class', 'timepicker-canvas-bearing'); - bearing.setAttribute('cx', '0'); - bearing.setAttribute('cy', '0'); - bearing.setAttribute('r', '4'); - const hand = Timepicker._createSVGEl('line'); - hand.setAttribute('x1', '0'); - hand.setAttribute('y1', '0'); - const bg = Timepicker._createSVGEl('circle'); - bg.setAttribute('class', 'timepicker-canvas-bg'); - bg.setAttribute('r', tickRadius.toString()); - g.appendChild(hand); - g.appendChild(bg); - g.appendChild(bearing); - svg.appendChild(g); - this._canvas.appendChild(svg); - this.hand = hand; - this.bg = bg; - this.bearing = bearing; - this.g = g; - } - _buildHoursView() { - // const $tick = document.createElement('div'); - // $tick.classList.add('timepicker-tick'); - // Hours view - if (this.options.twelveHour) { - for (let i = 1; i < 13; i += 1) { - // const tick = $tick.cloneNode(true); - const radian = (i / 6) * Math.PI; - const radius = this.options.outerRadius; - this._buildHoursTick(i, radian, radius); - } - } - else { - for (let i = 0; i < 24; i += 1) { - // const tick = $tick.cloneNode(true); - const radian = (i / 6) * Math.PI; - const inner = i > 0 && i < 13; - const radius = inner ? this.options.innerRadius : this.options.outerRadius; - this._buildHoursTick(i, radian, radius); - } - } - } - _buildHoursTick(i, radian, radius) { - const tick = document.createElement('div'); - tick.classList.add('timepicker-tick'); - tick.style.left = - this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px'; - tick.style.top = - this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px'; - tick.innerHTML = i === 0 ? '00' : i.toString(); - this.hoursView.appendChild(tick); - } - _buildMinutesView() { - const _tick = document.createElement('div'); - _tick.classList.add('timepicker-tick'); - // Minutes view - for (let i = 0; i < 60; i += 5) { - const tick = _tick.cloneNode(true); - const radian = (i / 30) * Math.PI; - tick.style.left = - this.options.dialRadius + - Math.sin(radian) * this.options.outerRadius - - this.options.tickRadius + - 'px'; - tick.style.top = - this.options.dialRadius - - Math.cos(radian) * this.options.outerRadius - - this.options.tickRadius + - 'px'; - tick.innerHTML = Timepicker._addLeadingZero(i); - this.minutesView.appendChild(tick); - } - } - _handleAmPmClick = (e) => { - this._handleAmPmInteraction(e.target); - }; - _handleAmPmKeypress = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleAmPmInteraction(e.target); - } - }; - _handleAmPmInteraction = (e) => { - this.amOrPm = e.classList.contains('am-btn') ? 'AM' : 'PM'; - this._updateAmPmView(); - }; - _updateAmPmView() { - if (this.options.twelveHour) { - if (this.amOrPm === 'PM') { - this._amBtn.classList.remove('filled'); - this._pmBtn.classList.add('filled'); - } - else if (this.amOrPm === 'AM') { - this._amBtn.classList.add('filled'); - this._pmBtn.classList.remove('filled'); - } - } - } - _updateTimeFromInput() { - // Get the time - let value = ((this.el.value || this.options.defaultTime || '') + '').split(':'); - if (this.options.twelveHour && !(typeof value[1] === 'undefined')) { - if (value[1].toUpperCase().indexOf('AM') > 0) { - this.amOrPm = 'AM'; - } - else { - this.amOrPm = 'PM'; - } - value[1] = value[1].replace('AM', '').replace('PM', ''); - } - if (value[0] === 'now') { - const now = new Date(+new Date() + this.options.fromNow); - value = [now.getHours().toString(), now.getMinutes().toString()]; - if (this.options.twelveHour) { - this.amOrPm = parseInt(value[0]) >= 12 && parseInt(value[0]) < 24 ? 'PM' : 'AM'; - } - } - this.hours = +value[0] || 0; - this.minutes = +value[1] || 0; - this.inputHours.value = Timepicker._addLeadingZero(this.hours); - this.inputMinutes.value = Timepicker._addLeadingZero(this.minutes); - this._updateAmPmView(); - } - /** - * Show hours or minutes view on timepicker. - * @param view The name of the view you want to switch to, 'hours' or 'minutes'. - * @param delay - */ - showView = (view, delay = null) => { - if (view === 'minutes' && getComputedStyle(this.hoursView).visibility === 'visible') ; - const isHours = view === 'hours', nextView = isHours ? this.hoursView : this.minutesView, hideView = isHours ? this.minutesView : this.hoursView; - this.currentView = view; - /*if (isHours) { - this.inputHours.classList.add('text-primary'); - this.inputMinutes.classList.remove('text-primary'); - } else { - this.inputHours.classList.remove('text-primary'); - this.inputMinutes.classList.add('text-primary'); - }*/ - // Transition view - hideView.classList.add('timepicker-dial-out'); - nextView.style.visibility = 'visible'; - nextView.classList.remove('timepicker-dial-out'); - // Reset clock hand - this.resetClock(delay); - // After transitions ended - clearTimeout(this.toggleViewTimer); - this.toggleViewTimer = setTimeout(() => { - hideView.style.visibility = 'hidden'; - }, this.options.duration); - }; - resetClock(delay) { - const view = this.currentView, value = this[view], isHours = view === 'hours', unit = Math.PI / (isHours ? 6 : 30), radian = value * unit, radius = isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius, x = Math.sin(radian) * radius, y = -Math.cos(radian) * radius; - if (delay) { - this._canvas?.classList.add('timepicker-canvas-out'); - setTimeout(() => { - this._canvas?.classList.remove('timepicker-canvas-out'); - this.setHand(x, y); - }, delay); - } - else { - this.setHand(x, y); - } - } - _inputFromTextField = () => { - const isHours = this.currentView === 'hours'; - if (isHours && this.inputHours.value !== '') { - const value = parseInt(this.inputHours.value); - if (value > 0 && value < (this.options.twelveHour ? 13 : 24)) { - this.hours = value; - } - else { - this.setHoursDefault(); - } - this.drawClockFromTimeInput(this.hours, isHours); - } - else if (!isHours && this.inputMinutes.value !== '') { - const value = parseInt(this.inputMinutes.value); - if (value >= 0 && value < 60) { - this.minutes = value; - } - else { - this.minutes = new Date().getMinutes(); - this.inputMinutes.value = this.minutes.toString(); - } - this.drawClockFromTimeInput(this.minutes, isHours); - } - }; - drawClockFromTimeInput(value, isHours) { - const unit = Math.PI / (isHours ? 6 : 30); - const radian = value * unit; - let radius; - if (this.options.twelveHour) { - radius = this.options.outerRadius; - } - else { - radius = - isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius; - } - this.setClockAttributes(radian, radius); - } - setHand(x, y, roundBy5 = false) { - const isHours = this.currentView === 'hours', unit = Math.PI / (isHours || roundBy5 ? 6 : 30), z = Math.sqrt(x * x + y * y), inner = isHours && z < (this.options.outerRadius + this.options.innerRadius) / 2; - let radian = Math.atan2(x, -y), radius = inner ? this.options.innerRadius : this.options.outerRadius; - if (this.options.twelveHour) { - radius = this.options.outerRadius; - } - // Radian should in range [0, 2PI] - if (radian < 0) { - radian = Math.PI * 2 + radian; - } - // Get the round value - let value = Math.round(radian / unit); - // Get the round radian - radian = value * unit; - // Correct the hours or minutes - if (this.options.twelveHour) { - if (isHours) { - if (value === 0) - value = 12; - } - else { - if (roundBy5) - value *= 5; - if (value === 60) - value = 0; - } - } - else { - if (isHours) { - if (value === 12) { - value = 0; - } - value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12; - } - else { - if (roundBy5) { - value *= 5; - } - if (value === 60) { - value = 0; - } - } - } - // Once hours or minutes changed, vibrate the device - if (this[this.currentView] !== value) { - if (this.vibrate && this.options.vibrate) { - // Do not vibrate too frequently - if (!this.vibrateTimer) { - navigator[this.vibrate](10); - this.vibrateTimer = setTimeout(() => { - this.vibrateTimer = null; - }, 100); - } - } - } - this[this.currentView] = value; - if (isHours) { - this.inputHours.value = Timepicker._addLeadingZero(value); - } - else { - this.inputMinutes.value = Timepicker._addLeadingZero(value); - } - // Set clock hand and others' position - this.setClockAttributes(radian, radius); - } - setClockAttributes(radian, radius) { - const cx1 = Math.sin(radian) * (radius - this.options.tickRadius), cy1 = -Math.cos(radian) * (radius - this.options.tickRadius), cx2 = Math.sin(radian) * radius, cy2 = -Math.cos(radian) * radius; - this.hand.setAttribute('x2', cx1.toString()); - this.hand.setAttribute('y2', cy1.toString()); - this.bg.setAttribute('cx', cx2.toString()); - this.bg.setAttribute('cy', cy2.toString()); - } - formatHours() { - if (this.inputHours.value == '') - this.setHoursDefault(); - this.inputHours.value = Timepicker._addLeadingZero(Number(this.inputHours.value)); - } - formatMinutes() { - if (this.inputMinutes.value == '') - this.minutes = new Date().getMinutes(); - this.inputMinutes.value = Timepicker._addLeadingZero(Number(this.inputMinutes.value)); - } - setHoursDefault() { - this.hours = new Date().getHours(); - this.inputHours.value = (this.hours % (this.options.twelveHour ? 12 : 24)).toString(); - } - done = (clearValue = null) => { - // Set input value - const last = this.el.value; - let value = clearValue - ? '' - : Timepicker._addLeadingZero(this.hours) + ':' + Timepicker._addLeadingZero(this.minutes); - this.time = value; - if (!clearValue && this.options.twelveHour) { - value = `${value} ${this.amOrPm}`; - } - this.el.value = value; - // Trigger change event - if (value !== last) { - this.el.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); - } - }; - confirm = () => { - this.done(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onDone === 'function') - this.options.onDone.call(this); - }; - cancel = () => { - // not logical clearing the input field on cancel, since the end user might want to make use of the previously submitted value - // this.clear(); - if (this.displayPlugin) - this.displayPlugin.hide(); - if (typeof this.options.onCancel === 'function') - this.options.onCancel.call(this); - }; - clear = () => { - // @todo should clear timepicker hour/minute input elems and reset analog clock, currently clears input el - this.done(true); - }; - // deprecated - open() { - console.warn('Timepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - close() { - console.warn('Timepicker.close() is deprecated. Remove this method and wrap in modal yourself.'); - return this; - } - static { - Timepicker._template = `
-
-
-
-
- -
-
- : -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
`; - } -} - -const _defaults$7 = { - text: '', - displayLength: 4000, - inDuration: 300, - outDuration: 375, - classes: '', - completeCallback: null, - activationPercent: 0.8 -}; -class Toast { - /** The toast element. */ - el; - /** - * The remaining amount of time in ms that the toast - * will stay before dismissal. - */ - timeRemaining; - /** - * Describes the current pan state of the Toast. - */ - panning; - options; - message; - counterInterval; - wasSwiped; - startingXPos; - xPos; - time; - deltaX; - velocityX; - static _toasts; - static _container; - static _draggedToast; - constructor(options) { - this.options = { - ...Toast.defaults, - ...options - }; - this.message = this.options.text; - this.panning = false; - this.timeRemaining = this.options.displayLength; - if (Toast._toasts.length === 0) { - Toast._createContainer(); - } - // Create new toast - Toast._toasts.push(this); - const toastElement = this._createToast(); - toastElement['M_Toast'] = this; - this.el = toastElement; - this._animateIn(); - this._setTimer(); - } - static get defaults() { - return _defaults$7; - } - static getInstance(el) { - return el['M_Toast']; - } - static _createContainer() { - const container = document.createElement('div'); - container.setAttribute('id', 'toast-container'); - // Add event handler - container.addEventListener('touchstart', Toast._onDragStart); - container.addEventListener('touchmove', Toast._onDragMove); - container.addEventListener('touchend', Toast._onDragEnd); - container.addEventListener('mousedown', Toast._onDragStart); - document.addEventListener('mousemove', Toast._onDragMove); - document.addEventListener('mouseup', Toast._onDragEnd); - document.body.appendChild(container); - Toast._container = container; - } - static _removeContainer() { - document.removeEventListener('mousemove', Toast._onDragMove); - document.removeEventListener('mouseup', Toast._onDragEnd); - if (Toast._container) { - Toast._container.remove(); - Toast._container = null; - } - } - static _onDragStart(e) { - if (e.target && e.target.closest('.toast')) { - const toastElem = e.target.closest('.toast'); - const toast = toastElem['M_Toast']; - toast.panning = true; - Toast._draggedToast = toast; - toast.el.classList.add('panning'); - toast.el.style.transition = ''; - toast.startingXPos = Toast._xPos(e); - toast.time = Date.now(); - toast.xPos = Toast._xPos(e); - } - } - static _onDragMove(e) { - if (!!Toast._draggedToast) { - e.preventDefault(); - const toast = Toast._draggedToast; - toast.deltaX = Math.abs(toast.xPos - Toast._xPos(e)); - toast.xPos = Toast._xPos(e); - toast.velocityX = toast.deltaX / (Date.now() - toast.time); - toast.time = Date.now(); - const totalDeltaX = toast.xPos - toast.startingXPos; - const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; - toast.el.style.transform = `translateX(${totalDeltaX}px)`; - toast.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString(); - } - } - static _onDragEnd() { - if (!!Toast._draggedToast) { - const toast = Toast._draggedToast; - toast.panning = false; - toast.el.classList.remove('panning'); - const totalDeltaX = toast.xPos - toast.startingXPos; - const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; - const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || toast.velocityX > 1; - // Remove toast - if (shouldBeDismissed) { - toast.wasSwiped = true; - toast.dismiss(); - // Animate toast back to original position - } - else { - toast.el.style.transition = 'transform .2s, opacity .2s'; - toast.el.style.transform = ''; - toast.el.style.opacity = ''; - } - Toast._draggedToast = null; - } - } - static _xPos(e) { - if (e.type.startsWith('touch') && e.targetTouches.length >= 1) { - return e.targetTouches[0].clientX; - } - // mouse event - return e.clientX; - } - /** - * dismiss all toasts. - */ - static dismissAll() { - for (const toastIndex in Toast._toasts) { - Toast._toasts[toastIndex].dismiss(); - } - } - _createToast() { - let toast = this.options.toastId - ? document.getElementById(this.options.toastId) - : document.createElement('div'); - if (toast instanceof HTMLTemplateElement) { - const node = toast.content.cloneNode(true); - toast = node.firstElementChild; - } - toast.classList.add('toast'); - toast.setAttribute('role', 'alert'); - toast.setAttribute('aria-live', 'assertive'); - toast.setAttribute('aria-atomic', 'true'); - // Add custom classes onto toast - if (this.options.classes.length > 0) { - toast.classList.add(...this.options.classes.split(' ')); - } - if (this.message) - toast.innerText = this.message; - if (Toast._container) { - Toast._container.appendChild(toast); - } - return toast; - } - _animateIn() { - // Animate toast in - this.el.style.display = ''; - this.el.style.opacity = '0'; - // easeOutCubic - this.el.style.transition = ` - top ${this.options.inDuration}ms ease, - opacity ${this.options.inDuration}ms ease - `; - setTimeout(() => { - this.el.style.top = '0'; - this.el.style.opacity = '1'; - }, 1); - } - /** - * Create setInterval which automatically removes toast when timeRemaining >= 0 - * has been reached. - */ - _setTimer() { - if (this.timeRemaining !== Infinity) { - this.counterInterval = setInterval(() => { - // If toast is not being dragged, decrease its time remaining - if (!this.panning) { - this.timeRemaining -= 20; - } - // Animate toast out - if (this.timeRemaining <= 0) { - this.dismiss(); - } - }, 20); - } - } - /** - * Dismiss toast with animation. - */ - dismiss() { - clearInterval(this.counterInterval); - const activationDistance = this.el.offsetWidth * this.options.activationPercent; - if (this.wasSwiped) { - this.el.style.transition = 'transform .05s, opacity .05s'; - this.el.style.transform = `translateX(${activationDistance}px)`; - this.el.style.opacity = '0'; - } - // easeOutExpo - this.el.style.transition = ` - margin ${this.options.outDuration}ms ease, - opacity ${this.options.outDuration}ms ease`; - setTimeout(() => { - this.el.style.opacity = '0'; - this.el.style.marginTop = '-40px'; - }, 1); - setTimeout(() => { - // Call the optional callback - if (typeof this.options.completeCallback === 'function') { - this.options.completeCallback(); - } - // Remove toast from DOM - if (this.el.id != this.options.toastId) { - this.el.remove(); - Toast._toasts.splice(Toast._toasts.indexOf(this), 1); - if (Toast._toasts.length === 0) { - Toast._removeContainer(); - } - } - }, this.options.outDuration); - } - static { - Toast._toasts = []; - Toast._container = null; - Toast._draggedToast = null; - } -} - -const _defaults$6 = { - exitDelay: 200, - enterDelay: 0, - text: '', - margin: 5, - inDuration: 250, - outDuration: 200, - position: 'bottom', - transitionMovement: 10, - opacity: 1 -}; -class Tooltip extends Component { - /** - * If tooltip is open. - */ - isOpen; - /** - * If tooltip is hovered. - */ - isHovered; - /** - * If tooltip is focused. - */ - isFocused; - tooltipEl; - _exitDelayTimeout; - _enterDelayTimeout; - xMovement; - yMovement; - constructor(el, options) { - super(el, options, Tooltip); - this.el['M_Tooltip'] = this; - this.options = { - ...Tooltip.defaults, - ...this._getAttributeOptions(), - ...options - }; - this.isOpen = false; - this.isHovered = false; - this.isFocused = false; - this._appendTooltipEl(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$6; - } - /** - * Initializes instances of Tooltip. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Tooltip); - } - static getInstance(el) { - return el['M_Tooltip']; - } - destroy() { - this.tooltipEl.remove(); - this._removeEventHandlers(); - this.el['M_Tooltip'] = undefined; - } - _appendTooltipEl() { - this.tooltipEl = document.createElement('div'); - this.tooltipEl.classList.add('material-tooltip'); - const tooltipContentEl = this.options.tooltipId - ? document.getElementById(this.options.tooltipId) - : document.createElement('div'); - this.tooltipEl.append(tooltipContentEl); - tooltipContentEl.style.display = ''; - tooltipContentEl.classList.add('tooltip-content'); - this._setTooltipContent(tooltipContentEl); - this.tooltipEl.appendChild(tooltipContentEl); - document.body.appendChild(this.tooltipEl); - } - _setTooltipContent(tooltipContentEl) { - if (this.options.tooltipId) - return; - tooltipContentEl.innerText = this.options.text; - } - _updateTooltipContent() { - this._setTooltipContent(this.tooltipEl.querySelector('.tooltip-content')); - } - _setupEventHandlers() { - this.el.addEventListener('mouseenter', this._handleMouseEnter); - this.el.addEventListener('mouseleave', this._handleMouseLeave); - this.el.addEventListener('focus', this._handleFocus, true); - this.el.addEventListener('blur', this._handleBlur, true); - } - _removeEventHandlers() { - this.el.removeEventListener('mouseenter', this._handleMouseEnter); - this.el.removeEventListener('mouseleave', this._handleMouseLeave); - this.el.removeEventListener('focus', this._handleFocus, true); - this.el.removeEventListener('blur', this._handleBlur, true); - } - /** - * Show tooltip. - */ - open = (isManual) => { - if (this.isOpen) - return; - isManual = isManual === undefined ? true : undefined; // Default value true - this.isOpen = true; - // Update tooltip content with HTML attribute options - this.options = { ...this.options, ...this._getAttributeOptions() }; - this._updateTooltipContent(); - this._setEnterDelayTimeout(isManual); - }; - /** - * Hide tooltip. - */ - close = () => { - if (!this.isOpen) - return; - this.isHovered = false; - this.isFocused = false; - this.isOpen = false; - this._setExitDelayTimeout(); - }; - _setExitDelayTimeout() { - clearTimeout(this._exitDelayTimeout); - this._exitDelayTimeout = setTimeout(() => { - if (this.isHovered || this.isFocused) - return; - this._animateOut(); - }, this.options.exitDelay); - } - _setEnterDelayTimeout(isManual) { - clearTimeout(this._enterDelayTimeout); - this._enterDelayTimeout = setTimeout(() => { - if (!this.isHovered && !this.isFocused && !isManual) - return; - this._animateIn(); - }, this.options.enterDelay); - } - _positionTooltip() { - const tooltip = this.tooltipEl; - const origin = this.el, originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, tooltipHeight = tooltip.offsetHeight, tooltipWidth = tooltip.offsetWidth, margin = this.options.margin; - this.xMovement = 0; - this.yMovement = 0; - let targetTop = origin.getBoundingClientRect().top + Utils.getDocumentScrollTop(); - let targetLeft = origin.getBoundingClientRect().left + Utils.getDocumentScrollLeft(); - if (this.options.position === 'top') { - targetTop += -tooltipHeight - margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = -this.options.transitionMovement; - } - else if (this.options.position === 'right') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += originWidth + margin; - this.xMovement = this.options.transitionMovement; - } - else if (this.options.position === 'left') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += -tooltipWidth - margin; - this.xMovement = -this.options.transitionMovement; - } - else { - targetTop += originHeight + margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = this.options.transitionMovement; - } - const newCoordinates = this._repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); - tooltip.style.top = newCoordinates.y + 'px'; - tooltip.style.left = newCoordinates.x + 'px'; - } - _repositionWithinScreen(x, y, width, height) { - const scrollLeft = Utils.getDocumentScrollLeft(); - const scrollTop = Utils.getDocumentScrollTop(); - let newX = x - scrollLeft; - let newY = y - scrollTop; - const bounding = { - left: newX, - top: newY, - width: width, - height: height - }; - const offset = this.options.margin + this.options.transitionMovement; - const edges = Utils.checkWithinContainer(document.body, bounding, offset); - if (edges.left) { - newX = offset; - } - else if (edges.right) { - newX -= newX + width - window.innerWidth; - } - if (edges.top) { - newY = offset; - } - else if (edges.bottom) { - newY -= newY + height - window.innerHeight; - } - return { - x: newX + scrollLeft, - y: newY + scrollTop - }; - } - _animateIn() { - this._positionTooltip(); - this.tooltipEl.style.visibility = 'visible'; - const duration = this.options.inDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`; - this.tooltipEl.style.opacity = (this.options.opacity || 1).toString(); - }, 1); - } - _animateOut() { - const duration = this.options.outDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`; - this.tooltipEl.style.opacity = '0'; - }, 1); - /* - anim.remove(this.tooltipEl); - anim({ - targets: this.tooltipEl, - opacity: 0, - translateX: 0, - translateY: 0, - duration: this.options.outDuration, - easing: 'easeOutCubic' - }); - */ - } - _handleMouseEnter = () => { - this.isHovered = true; - this.isFocused = false; // Allows close of tooltip when opened by focus. - this.open(false); - }; - _handleMouseLeave = () => { - this.isHovered = false; - this.isFocused = false; // Allows close of tooltip when opened by focus. - this.close(); - }; - _handleFocus = () => { - if (Utils.tabPressed) { - this.isFocused = true; - this.open(false); - } - }; - _handleBlur = () => { - this.isFocused = false; - this.close(); - }; - _getAttributeOptions() { - const attributeOptions = {}; - const tooltipTextOption = this.el.getAttribute('data-tooltip'); - const tooltipId = this.el.getAttribute('data-tooltip-id'); - const positionOption = this.el.getAttribute('data-position'); - if (tooltipTextOption) { - attributeOptions.text = tooltipTextOption; - } - if (positionOption) { - attributeOptions.position = positionOption; - } - if (tooltipId) { - attributeOptions.tooltipId = tooltipId; - } - return attributeOptions; - } -} - -const _defaults$5 = {}; -// TODO: !!!!! -class Range extends Component { - _mousedown; - value; - thumb; - constructor(el, options) { - super(el, options, Range); - this.el['M_Range'] = this; - this.options = { - ...Range.defaults, - ...options - }; - this._mousedown = false; - this._setupThumb(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$5; - } - /** - * Initializes instances of Range. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Range); - } - static getInstance(el) { - return el['M_Range']; - } - destroy() { - this._removeEventHandlers(); - this._removeThumb(); - this.el['M_Range'] = undefined; - } - _setupEventHandlers() { - this.el.addEventListener('change', this._handleRangeChange); - this.el.addEventListener('mousedown', this._handleRangeMousedownTouchstart); - this.el.addEventListener('touchstart', this._handleRangeMousedownTouchstart); - this.el.addEventListener('input', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('mousemove', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('touchmove', this._handleRangeInputMousemoveTouchmove); - this.el.addEventListener('mouseup', this._handleRangeMouseupTouchend); - this.el.addEventListener('touchend', this._handleRangeMouseupTouchend); - this.el.addEventListener('blur', this._handleRangeBlurMouseoutTouchleave); - this.el.addEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave); - this.el.addEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave); - } - _removeEventHandlers() { - this.el.removeEventListener('change', this._handleRangeChange); - this.el.removeEventListener('mousedown', this._handleRangeMousedownTouchstart); - this.el.removeEventListener('touchstart', this._handleRangeMousedownTouchstart); - this.el.removeEventListener('input', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('mousemove', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('touchmove', this._handleRangeInputMousemoveTouchmove); - this.el.removeEventListener('mouseup', this._handleRangeMouseupTouchend); - this.el.removeEventListener('touchend', this._handleRangeMouseupTouchend); - this.el.removeEventListener('blur', this._handleRangeBlurMouseoutTouchleave); - this.el.removeEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave); - this.el.removeEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave); - } - _handleRangeChange = () => { - this.value.innerHTML = this.el.value; - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - }; - _handleRangeMousedownTouchstart = (e) => { - // Set indicator value - this.value.innerHTML = this.el.value; - this._mousedown = true; - this.el.classList.add('active'); - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - if (e.type !== 'input') { - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - } - }; - _handleRangeInputMousemoveTouchmove = () => { - if (this._mousedown) { - if (!this.thumb.classList.contains('active')) { - this._showRangeBubble(); - } - const offsetLeft = this._calcRangeOffset(); - this.thumb.classList.add('active'); - this.thumb.style.left = offsetLeft + 'px'; - this.value.innerHTML = this.el.value; - } - }; - _handleRangeMouseupTouchend = () => { - this._mousedown = false; - this.el.classList.remove('active'); - }; - _handleRangeBlurMouseoutTouchleave = () => { - if (!this._mousedown) { - const paddingLeft = parseInt(getComputedStyle(this.el).paddingLeft); - const marginLeftText = 7 + paddingLeft + 'px'; - if (this.thumb.classList.contains('active')) { - const duration = 100; - // from - this.thumb.style.transition = 'none'; - setTimeout(() => { - this.thumb.style.transition = ` - height ${duration}ms ease, - width ${duration}ms ease, - top ${duration}ms ease, - margin ${duration}ms ease - `; - // to - this.thumb.style.height = '0'; - this.thumb.style.width = '0'; - this.thumb.style.top = '0'; - this.thumb.style.marginLeft = marginLeftText; - }, 1); - } - this.thumb.classList.remove('active'); - } - }; - _setupThumb() { - this.thumb = document.createElement('span'); - this.value = document.createElement('span'); - this.thumb.classList.add('thumb'); - this.value.classList.add('value'); - this.thumb.append(this.value); - this.el.after(this.thumb); - } - _removeThumb() { - this.thumb.remove(); - } - _showRangeBubble() { - const paddingLeft = parseInt(getComputedStyle(this.thumb.parentElement).paddingLeft); - const marginLeftText = -7 + paddingLeft + 'px'; // TODO: fix magic number? - const duration = 300; - // easeOutQuint - this.thumb.style.transition = ` - height ${duration}ms ease, - width ${duration}ms ease, - top ${duration}ms ease, - margin ${duration}ms ease - `; - // to - this.thumb.style.height = '30px'; - this.thumb.style.width = '30px'; - this.thumb.style.top = '-30px'; - this.thumb.style.marginLeft = marginLeftText; - } - _calcRangeOffset() { - const width = this.el.getBoundingClientRect().width - 15; - const max = parseFloat(this.el.getAttribute('max')) || 100; // Range default max - const min = parseFloat(this.el.getAttribute('min')) || 0; // Range default min - const percent = (parseFloat(this.el.value) - min) / (max - min); - return percent * width; - } - /** - * Initializes every range input in the current document. - */ - static Init() { - if (typeof document !== 'undefined') - Range.init(document?.querySelectorAll('input[type=range]'), {}); - } -} - -const _defaults$4 = { - onOpen: null, - onClose: null -}; -class TapTarget extends Component { - /** - * If the tap target is open. - */ - isOpen; - static _taptargets; - wrapper; - // private _origin: HTMLElement; - originEl; - waveEl; - contentEl; - constructor(el, options) { - super(el, options, TapTarget); - this.el['M_TapTarget'] = this; - this.options = { - ...TapTarget.defaults, - ...options - }; - this.isOpen = false; - // setup - this.originEl = document.querySelector(`#${el.dataset.target}`); - this.originEl.tabIndex = 0; - this._setup(); - this._calculatePositioning(); - this._setupEventHandlers(); - TapTarget._taptargets.push(this); - } - static get defaults() { - return _defaults$4; - } - /** - * Initializes instances of TapTarget. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, TapTarget); - } - static getInstance(el) { - return el['M_TapTarget']; - } - destroy() { - this._removeEventHandlers(); - this.el['M_TapTarget'] = undefined; - const index = TapTarget._taptargets.indexOf(this); - if (index >= 0) { - TapTarget._taptargets.splice(index, 1); - } - } - _setupEventHandlers() { - this.originEl.addEventListener('click', this._handleTargetToggle); - this.originEl.addEventListener('keypress', this._handleKeyboardInteraction, true); - // this.originEl.addEventListener('click', this._handleOriginClick); - // Resize - window.addEventListener('resize', this._handleThrottledResize); - } - _removeEventHandlers() { - this.originEl.removeEventListener('click', this._handleTargetToggle); - this.originEl.removeEventListener('keypress', this._handleKeyboardInteraction, true); - // this.originEl.removeEventListener('click', this._handleOriginClick); - window.removeEventListener('resize', this._handleThrottledResize); - } - _handleThrottledResize = () => Utils.throttle(this._handleResize, 200).bind(this); - _handleKeyboardInteraction = (e) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleTargetToggle(); - } - }; - _handleTargetToggle = () => { - if (!this.isOpen) - this.open(); - else - this.close(); - }; - /*_handleOriginClick = () => { - this.close(); - }*/ - _handleResize = () => { - this._calculatePositioning(); - }; - _handleDocumentClick = (e) => { - if (e.target.closest(`#${this.el.dataset.target}`) !== this.originEl && - !e.target.closest('.tap-target-wrapper')) { - this.close(); - // e.preventDefault(); - // e.stopPropagation(); - } - }; - _setup() { - // Creating tap target - this.wrapper = this.el.parentElement; - this.waveEl = this.wrapper.querySelector('.tap-target-wave'); - this.el.parentElement.ariaExpanded = 'false'; - this.originEl.style.zIndex = '1002'; - // this.originEl = this.wrapper.querySelector('.tap-target-origin'); - this.contentEl = this.el.querySelector('.tap-target-content'); - // Creating wrapper - if (!this.wrapper.classList.contains('.tap-target-wrapper')) { - this.wrapper = document.createElement('div'); - this.wrapper.classList.add('tap-target-wrapper'); - this.el.before(this.wrapper); - this.wrapper.append(this.el); - } - // Creating content - if (!this.contentEl) { - this.contentEl = document.createElement('div'); - this.contentEl.classList.add('tap-target-content'); - this.el.append(this.contentEl); - } - // Creating foreground wave - if (!this.waveEl) { - this.waveEl = document.createElement('div'); - this.waveEl.classList.add('tap-target-wave'); - // Creating origin - /*if (!this.originEl) { - this.originEl = this._origin.cloneNode(true); // .clone(true, true); - this.originEl.classList.add('tap-target-origin'); - this.originEl.removeAttribute('id'); - this.originEl.removeAttribute('style'); - this.waveEl.append(this.originEl); - }*/ - this.wrapper.append(this.waveEl); - } - } - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - _calculatePositioning() { - // Element or parent is fixed position? - let isFixed = getComputedStyle(this.originEl).position === 'fixed'; - if (!isFixed) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let currentElem = this.originEl; - const parents = []; - while ((currentElem = currentElem.parentNode) && currentElem !== document) - parents.push(currentElem); - for (let i = 0; i < parents.length; i++) { - isFixed = getComputedStyle(parents[i]).position === 'fixed'; - if (isFixed) - break; - } - } - // Calculating origin - const originWidth = this.originEl.offsetWidth; - const originHeight = this.originEl.offsetHeight; - const originTop = isFixed - ? this._offset(this.originEl).top - Utils.getDocumentScrollTop() - : this._offset(this.originEl).top; - const originLeft = isFixed - ? this._offset(this.originEl).left - Utils.getDocumentScrollLeft() - : this._offset(this.originEl).left; - // Calculating screen - const windowWidth = window.innerWidth; - const windowHeight = window.innerHeight; - const scrollBarWidth = windowWidth - document.documentElement.clientWidth; - const centerX = windowWidth / 2; - const centerY = windowHeight / 2; - const isLeft = originLeft <= centerX; - const isRight = originLeft > centerX; - const isTop = originTop <= centerY; - const isBottom = originTop > centerY; - const isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75; - // Calculating tap target - const tapTargetWidth = this.el.offsetWidth; - const tapTargetHeight = this.el.offsetHeight; - const tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2; - const tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2; - const tapTargetPosition = isFixed ? 'fixed' : 'absolute'; - // Calculating content - const tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth; - const tapTargetTextHeight = tapTargetHeight / 2; - const tapTargetTextTop = isTop ? tapTargetHeight / 2 : 0; - const tapTargetTextBottom = 0; - const tapTargetTextLeft = isLeft && !isCenterX ? tapTargetWidth / 2 - originWidth : 0; - const tapTargetTextRight = 0; - const tapTargetTextPadding = originWidth; - const tapTargetTextAlign = isBottom ? 'bottom' : 'top'; - // Calculating wave - const tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2; - const tapTargetWaveHeight = tapTargetWaveWidth; - const tapTargetWaveTop = tapTargetHeight / 2 - tapTargetWaveHeight / 2; - const tapTargetWaveLeft = tapTargetWidth / 2 - tapTargetWaveWidth / 2; - // Setting tap target - this.wrapper.style.top = isTop ? tapTargetTop + 'px' : ''; - this.wrapper.style.right = isRight - ? windowWidth - tapTargetLeft - tapTargetWidth - scrollBarWidth + 'px' - : ''; - this.wrapper.style.bottom = isBottom - ? windowHeight - tapTargetTop - tapTargetHeight + 'px' - : ''; - this.wrapper.style.left = isLeft ? tapTargetLeft + 'px' : ''; - this.wrapper.style.position = tapTargetPosition; - // Setting content - this.contentEl.style.width = tapTargetTextWidth + 'px'; - this.contentEl.style.height = tapTargetTextHeight + 'px'; - this.contentEl.style.top = tapTargetTextTop + 'px'; - this.contentEl.style.right = tapTargetTextRight + 'px'; - this.contentEl.style.bottom = tapTargetTextBottom + 'px'; - this.contentEl.style.left = tapTargetTextLeft + 'px'; - this.contentEl.style.padding = tapTargetTextPadding + 'px'; - this.contentEl.style.verticalAlign = tapTargetTextAlign; - // Setting wave - this.waveEl.style.top = tapTargetWaveTop + 'px'; - this.waveEl.style.left = tapTargetWaveLeft + 'px'; - this.waveEl.style.width = tapTargetWaveWidth + 'px'; - this.waveEl.style.height = tapTargetWaveHeight + 'px'; - } - /** - * Open Tap Target. - */ - open = () => { - if (this.isOpen) - return; - // onOpen callback - if (typeof this.options.onOpen === 'function') { - this.options.onOpen.call(this, this.originEl); - } - this.isOpen = true; - this.wrapper.classList.add('open'); - this.wrapper.ariaExpanded = 'true'; - document.body.addEventListener('click', this._handleDocumentClick, true); - document.body.addEventListener('keypress', this._handleDocumentClick, true); - document.body.addEventListener('touchend', this._handleDocumentClick); - }; - /** - * Close Tap Target. - */ - close = () => { - if (!this.isOpen) - return; - // onClose callback - if (typeof this.options.onClose === 'function') { - this.options.onClose.call(this, this.originEl); - } - this.isOpen = false; - this.wrapper.classList.remove('open'); - this.wrapper.ariaExpanded = 'false'; - document.body.removeEventListener('click', this._handleDocumentClick, true); - document.body.removeEventListener('keypress', this._handleDocumentClick, true); - document.body.removeEventListener('touchend', this._handleDocumentClick); - }; - static { - TapTarget._taptargets = []; - } -} - -const _defaults$3 = Object.freeze({}); -class CharacterCounter extends Component { - /** Stores the reference to the counter HTML element. */ - counterEl; - /** Specifies whether the input is valid or not. */ - isInvalid; - /** Specifies whether the input text has valid length or not. */ - isValidLength; - constructor(el, options) { - super(el, {}, CharacterCounter); - this.el['M_CharacterCounter'] = this; - this.options = { - ...CharacterCounter.defaults, - ...options - }; - this.isInvalid = false; - this.isValidLength = false; - this._setupCounter(); - this._setupEventHandlers(); - } - static get defaults() { - return _defaults$3; - } - /** - * Initializes instances of CharacterCounter. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, CharacterCounter); - } - static getInstance(el) { - return el['M_CharacterCounter']; - } - destroy() { - this._removeEventHandlers(); - this.el['CharacterCounter'] = undefined; - this._removeCounter(); - } - _setupEventHandlers() { - this.el.addEventListener('focus', this.updateCounter, true); - this.el.addEventListener('input', this.updateCounter, true); - } - _removeEventHandlers() { - this.el.removeEventListener('focus', this.updateCounter, true); - this.el.removeEventListener('input', this.updateCounter, true); - } - _setupCounter() { - this.counterEl = document.createElement('span'); - this.counterEl.classList.add('character-counter'); - this.counterEl.style.float = 'right'; - this.counterEl.style.fontSize = '12px'; - this.counterEl.style.height = '1'; - this.el.parentElement.appendChild(this.counterEl); - } - _removeCounter() { - this.counterEl.remove(); - } - updateCounter = () => { - const maxLength = parseInt(this.el.getAttribute('maxlength')), actualLength = this.el.value.length; - this.isValidLength = actualLength <= maxLength; - let counterString = actualLength.toString(); - if (maxLength) { - counterString += '/' + maxLength; - this._validateInput(); - } - this.counterEl.innerHTML = counterString; - }; - _validateInput() { - if (this.isValidLength && this.isInvalid) { - this.isInvalid = false; - this.el.classList.remove('invalid'); - } - else if (!this.isValidLength && !this.isInvalid) { - this.isInvalid = true; - this.el.classList.remove('valid'); - this.el.classList.add('invalid'); - } - } -} - -const _defaults$2 = { - responsiveThreshold: 0 // breakpoint for swipeable -}; -class Parallax extends Component { - _enabled; - _img; - static _parallaxes = []; - static _handleScrollThrottled; - static _handleWindowResizeThrottled; - constructor(el, options) { - super(el, options, Parallax); - this.el['M_Parallax'] = this; - this.options = { - ...Parallax.defaults, - ...options - }; - this._enabled = window.innerWidth > this.options.responsiveThreshold; - this._img = this.el.querySelector('img'); - this._updateParallax(); - this._setupEventHandlers(); - this._setupStyles(); - Parallax._parallaxes.push(this); - } - static get defaults() { - return _defaults$2; - } - /** - * Initializes instances of Parallax. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Parallax); - } - static getInstance(el) { - return el['M_Parallax']; - } - destroy() { - Parallax._parallaxes.splice(Parallax._parallaxes.indexOf(this), 1); - this._img.style.transform = ''; - this._removeEventHandlers(); - this.el['M_Parallax'] = undefined; - } - static _handleScroll() { - for (let i = 0; i < Parallax._parallaxes.length; i++) { - const parallaxInstance = Parallax._parallaxes[i]; - parallaxInstance._updateParallax.call(parallaxInstance); - } - } - static _handleWindowResize() { - for (let i = 0; i < Parallax._parallaxes.length; i++) { - const parallaxInstance = Parallax._parallaxes[i]; - parallaxInstance._enabled = window.innerWidth > parallaxInstance.options.responsiveThreshold; - } - } - _setupEventHandlers() { - this._img.addEventListener('load', this._handleImageLoad); - if (Parallax._parallaxes.length === 0) { - if (!Parallax._handleScrollThrottled) { - Parallax._handleScrollThrottled = Utils.throttle(Parallax._handleScroll, 5); - } - if (!Parallax._handleWindowResizeThrottled) { - Parallax._handleWindowResizeThrottled = Utils.throttle(Parallax._handleWindowResize, 5); - } - window.addEventListener('scroll', Parallax._handleScrollThrottled); - window.addEventListener('resize', Parallax._handleWindowResizeThrottled); - } - } - _removeEventHandlers() { - this._img.removeEventListener('load', this._handleImageLoad); - if (Parallax._parallaxes.length === 0) { - window.removeEventListener('scroll', Parallax._handleScrollThrottled); - window.removeEventListener('resize', Parallax._handleWindowResizeThrottled); - } - } - _setupStyles() { - this._img.style.opacity = '1'; - } - _handleImageLoad = () => { - this._updateParallax(); - }; - _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.scrollY - docElem.clientTop, - left: box.left + window.scrollX - docElem.clientLeft - }; - } - _updateParallax() { - const containerHeight = this.el.getBoundingClientRect().height > 0 ? this.el.parentElement.offsetHeight : 500; - const imgHeight = this._img.offsetHeight; - const parallaxDist = imgHeight - containerHeight; - const bottom = this._offset(this.el).top + containerHeight; - const top = this._offset(this.el).top; - const scrollTop = Utils.getDocumentScrollTop(); - const windowHeight = window.innerHeight; - const windowBottom = scrollTop + windowHeight; - const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight); - const parallax = parallaxDist * percentScrolled; - if (!this._enabled) { - this._img.style.transform = ''; - } - else if (bottom > scrollTop && top < scrollTop + windowHeight) { - this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`; - } - } -} - -const _defaults$1 = { - top: 0, - bottom: Infinity, - offset: 0, - onPositionChange: null -}; -class Pushpin extends Component { - static _pushpins; - originalOffset; - constructor(el, options) { - super(el, options, Pushpin); - this.el['M_Pushpin'] = this; - this.options = { - ...Pushpin.defaults, - ...options - }; - this.originalOffset = this.el.offsetTop; - Pushpin._pushpins.push(this); - this._setupEventHandlers(); - this._updatePosition(); - } - static get defaults() { - return _defaults$1; - } - /** - * Initializes instances of Pushpin. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, Pushpin); - } - static getInstance(el) { - return el['M_Pushpin']; - } - destroy() { - this.el.style.top = null; - this._removePinClasses(); - // Remove pushpin Inst - const index = Pushpin._pushpins.indexOf(this); - Pushpin._pushpins.splice(index, 1); - if (Pushpin._pushpins.length === 0) { - this._removeEventHandlers(); - } - this.el['M_Pushpin'] = undefined; - } - static _updateElements() { - for (const elIndex in Pushpin._pushpins) { - const pInstance = Pushpin._pushpins[elIndex]; - pInstance._updatePosition(); - } - } - _setupEventHandlers() { - document.addEventListener('scroll', Pushpin._updateElements); - } - _removeEventHandlers() { - document.removeEventListener('scroll', Pushpin._updateElements); - } - _updatePosition() { - const scrolled = Utils.getDocumentScrollTop() + this.options.offset; - if (this.options.top <= scrolled && - this.options.bottom >= scrolled && - !this.el.classList.contains('pinned')) { - this._removePinClasses(); - this.el.style.top = `${this.options.offset}px`; - this.el.classList.add('pinned'); - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pinned'); - } - } - // Add pin-top (when scrolled position is above top) - if (scrolled < this.options.top && !this.el.classList.contains('pin-top')) { - this._removePinClasses(); - this.el.style.top = '0'; - this.el.classList.add('pin-top'); - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pin-top'); - } - } - // Add pin-bottom (when scrolled position is below bottom) - if (scrolled > this.options.bottom && !this.el.classList.contains('pin-bottom')) { - this._removePinClasses(); - this.el.classList.add('pin-bottom'); - this.el.style.top = `${this.options.bottom - this.originalOffset}px`; - // onPositionChange callback - if (typeof this.options.onPositionChange === 'function') { - this.options.onPositionChange.call(this, 'pin-bottom'); - } - } - } - _removePinClasses() { - // IE 11 bug (can't remove multiple classes in one line) - this.el.classList.remove('pin-top'); - this.el.classList.remove('pinned'); - this.el.classList.remove('pin-bottom'); - } - static { - Pushpin._pushpins = []; - } -} - -const _defaults = { - throttle: 100, - scrollOffset: 200, // offset - 200 allows elements near bottom of page to scroll - activeClass: 'active', - getActiveElement: (id) => { - return 'a[href="#' + id + '"]'; - }, - keepTopElementActive: false, - animationDuration: null -}; -class ScrollSpy extends Component { - static _elements; - static _count; - static _increment; - static _elementsInView; - static _visibleElements; - static _ticks; - static _keptTopActiveElement = null; - tickId; - id; - constructor(el, options) { - super(el, options, ScrollSpy); - this.el['M_ScrollSpy'] = this; - this.options = { - ...ScrollSpy.defaults, - ...options - }; - ScrollSpy._elements.push(this); - ScrollSpy._count++; - ScrollSpy._increment++; - this.tickId = -1; - this.id = ScrollSpy._increment.toString(); - this._setupEventHandlers(); - this._handleWindowScroll(); - } - static get defaults() { - return _defaults; - } - /** - * Initializes instances of ScrollSpy. - * @param els HTML elements. - * @param options Component options. - */ - static init(els, options = {}) { - return super.init(els, options, ScrollSpy); - } - static getInstance(el) { - return el['M_ScrollSpy']; - } - destroy() { - ScrollSpy._elements.splice(ScrollSpy._elements.indexOf(this), 1); - ScrollSpy._elementsInView.splice(ScrollSpy._elementsInView.indexOf(this), 1); - ScrollSpy._visibleElements.splice(ScrollSpy._visibleElements.indexOf(this.el), 1); - ScrollSpy._count--; - this._removeEventHandlers(); - const actElem = document.querySelector(this.options.getActiveElement(this.el.id)); - actElem.classList.remove(this.options.activeClass); - this.el['M_ScrollSpy'] = undefined; - } - _setupEventHandlers() { - if (ScrollSpy._count === 1) { - window.addEventListener('scroll', this._handleWindowScroll); - window.addEventListener('resize', this._handleThrottledResize); - document.body.addEventListener('click', this._handleTriggerClick); - } - } - _removeEventHandlers() { - if (ScrollSpy._count === 0) { - window.removeEventListener('scroll', this._handleWindowScroll); - window.removeEventListener('resize', this._handleThrottledResize); - document.body.removeEventListener('click', this._handleTriggerClick); - } - } - _handleThrottledResize = () => Utils.throttle(this._handleWindowScroll, 200).bind(this); - _handleTriggerClick = (e) => { - const trigger = e.target; - for (let i = ScrollSpy._elements.length - 1; i >= 0; i--) { - const scrollspy = ScrollSpy._elements[i]; - const x = document.querySelector('a[href="#' + scrollspy.el.id + '"]'); - if (trigger === x) { - e.preventDefault(); - if (scrollspy.el['M_ScrollSpy'].options.animationDuration) { - ScrollSpy._smoothScrollIntoView(scrollspy.el, scrollspy.el['M_ScrollSpy'].options.animationDuration); - } - else { - scrollspy.el.scrollIntoView({ behavior: 'smooth' }); - } - break; - } - } - }; - _handleWindowScroll = () => { - // unique tick id - ScrollSpy._ticks++; - // viewport rectangle - const top = Utils.getDocumentScrollTop(), left = Utils.getDocumentScrollLeft(), right = left + window.innerWidth, bottom = top + window.innerHeight; - // determine which elements are in view - const intersections = ScrollSpy._findElements(top, right, bottom, left); - for (let i = 0; i < intersections.length; i++) { - const scrollspy = intersections[i]; - const lastTick = scrollspy.tickId; - if (lastTick < 0) { - // entered into view - scrollspy._enter(); - } - // update tick id - scrollspy.tickId = ScrollSpy._ticks; - } - for (let i = 0; i < ScrollSpy._elementsInView.length; i++) { - const scrollspy = ScrollSpy._elementsInView[i]; - const lastTick = scrollspy.tickId; - if (lastTick >= 0 && lastTick !== ScrollSpy._ticks) { - // exited from view - scrollspy._exit(); - scrollspy.tickId = -1; - } - } - // remember elements in view for next tick - ScrollSpy._elementsInView = intersections; - if (ScrollSpy._elements.length) { - const options = ScrollSpy._elements[0].el['M_ScrollSpy'].options; - if (options.keepTopElementActive && ScrollSpy._visibleElements.length === 0) { - this._resetKeptTopActiveElementIfNeeded(); - const topElements = ScrollSpy._elements - .filter((value) => ScrollSpy._getDistanceToViewport(value.el) <= 0) - .sort((a, b) => { - const distanceA = ScrollSpy._getDistanceToViewport(a.el); - const distanceB = ScrollSpy._getDistanceToViewport(b.el); - if (distanceA < distanceB) - return -1; - if (distanceA > distanceB) - return 1; - return 0; - }); - const nearestTopElement = topElements.length - ? topElements[topElements.length - 1] - : ScrollSpy._elements[0]; - const actElem = document.querySelector(options.getActiveElement(nearestTopElement.el.id)); - actElem?.classList.add(options.activeClass); - ScrollSpy._keptTopActiveElement = actElem; - } - } - }; - static _offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - static _findElements(top, right, bottom, left) { - const hits = []; - for (let i = 0; i < ScrollSpy._elements.length; i++) { - const scrollspy = ScrollSpy._elements[i]; - const currTop = top + scrollspy.options.scrollOffset || 200; - if (scrollspy.el.getBoundingClientRect().height > 0) { - const elTop = ScrollSpy._offset(scrollspy.el).top, elLeft = ScrollSpy._offset(scrollspy.el).left, elRight = elLeft + scrollspy.el.getBoundingClientRect().width, elBottom = elTop + scrollspy.el.getBoundingClientRect().height; - const isIntersect = !(elLeft > right || - elRight < left || - elTop > bottom || - elBottom < currTop); - if (isIntersect) { - hits.push(scrollspy); - } - } - } - return hits; - } - _enter() { - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((value) => value.getBoundingClientRect().height !== 0); - if (ScrollSpy._visibleElements[0]) { - const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id)); - actElem?.classList.remove(this.options.activeClass); - if (ScrollSpy._visibleElements[0]['M_ScrollSpy'] && - this.id < ScrollSpy._visibleElements[0]['M_ScrollSpy'].id) { - ScrollSpy._visibleElements.unshift(this.el); - } - else { - ScrollSpy._visibleElements.push(this.el); - } - } - else { - ScrollSpy._visibleElements.push(this.el); - } - this._resetKeptTopActiveElementIfNeeded(); - const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id); - document.querySelector(selector)?.classList.add(this.options.activeClass); - } - _exit() { - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((value) => value.getBoundingClientRect().height !== 0); - if (ScrollSpy._visibleElements[0]) { - const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id)); - actElem?.classList.remove(this.options.activeClass); - ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((x) => x.id != this.el.id); - if (ScrollSpy._visibleElements[0]) { - // Check if empty - const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id); - document.querySelector(selector)?.classList.add(this.options.activeClass); - this._resetKeptTopActiveElementIfNeeded(); - } - } - } - _resetKeptTopActiveElementIfNeeded() { - if (ScrollSpy._keptTopActiveElement) { - ScrollSpy._keptTopActiveElement.classList.remove(this.options.activeClass); - ScrollSpy._keptTopActiveElement = null; - } - } - static _getDistanceToViewport(element) { - const rect = element.getBoundingClientRect(); - const distance = rect.top; - return distance; - } - static _smoothScrollIntoView(element, duration = 300) { - const targetPosition = element.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); - const startPosition = window.scrollY || window.pageYOffset; - const distance = targetPosition - startPosition; - const startTime = performance.now(); - function scrollStep(currentTime) { - const elapsed = currentTime - startTime; - const progress = Math.min(elapsed / duration, 1); - const scrollY = startPosition + distance * progress; - if (progress < 1) { - window.scrollTo(0, scrollY); - requestAnimationFrame(scrollStep); - } - else { - window.scrollTo(0, targetPosition); - } - } - requestAnimationFrame(scrollStep); - } - static { - ScrollSpy._elements = []; - ScrollSpy._elementsInView = []; - ScrollSpy._visibleElements = []; // Array. - ScrollSpy._count = 0; - ScrollSpy._increment = 0; - ScrollSpy._ticks = 0; - } -} - -// type RGBColor = { -// r: number; -// g: number; -// b: number; -// }; - -// type Position = { -// x: number; -// y: number; -// }; - -class Waves { - /** - * - * @param {HTMLElement} el - * @returns - */ - static #offset(el) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; - } - - // https://phoenix-dx.com/css-techniques-for-material-ripple-effect/ - - /** - * - * @param {HTMLElement} targetElement - * @param position - * @param color - */ - static renderWaveEffect(targetElement, position = null, color = null) { - const isCentered = position === null; - const duration = 500; - let animationFrame, animationStart; - - const animationStep = (timestamp) => { - if (!animationStart) animationStart = timestamp; - const frame = timestamp - animationStart; - if (frame < duration) { - const easing = (frame / duration) * (2 - frame / duration); - const circle = isCentered - ? 'circle at 50% 50%' - : `circle at ${position.x}px ${position.y}px`; - const waveColor = `rgba(${color?.r || 0}, ${color?.g || 0}, ${color?.b || 0}, ${0.3 * (1 - easing)})`; - const stop = 90 * easing + '%'; - targetElement.style.backgroundImage = - 'radial-gradient(' + - circle + - ', ' + - waveColor + - ' ' + - stop + - ', transparent ' + - stop + - ')'; - animationFrame = window.requestAnimationFrame(animationStep); - } else { - targetElement.style.backgroundImage = 'none'; - window.cancelAnimationFrame(animationFrame); - } - }; - - animationFrame = window.requestAnimationFrame(animationStep); - } - - static Init() { - if (typeof document !== 'undefined') - document?.addEventListener('DOMContentLoaded', () => { - document.body.addEventListener('click', (e) => { - const trigger = e.target; - const el = trigger.closest('.waves-effect'); - if (el && el.contains(trigger)) { - const isCircular = el.classList.contains('waves-circle'); - const x = e.pageX - this.#offset(el).left; - const y = e.pageY - this.#offset(el).top; - let color = null; - if (el.classList.contains('waves-light')) color = { r: 255, g: 255, b: 255 }; - this.renderWaveEffect(el, isCircular ? null : { x, y }, color); - } - }); - }); - } -} - -/* eslint-disable @typescript-eslint/no-unused-vars */ -const version = '2.3.3'; -/** - * Automatically initialize components. - * @param context Root element to initialize. Defaults to `document.body`. - * @param options Options for each component. - */ -function AutoInit(context = document.body, options) { - const registry = { - Autocomplete: context.querySelectorAll('.autocomplete:not(.no-autoinit)'), - Cards: context.querySelectorAll('.cards:not(.no-autoinit)'), - Carousel: context.querySelectorAll('.carousel:not(.no-autoinit)'), - Chips: context.querySelectorAll('.chips:not(.no-autoinit)'), - Collapsible: context.querySelectorAll('.collapsible:not(.no-autoinit)'), - Datepicker: context.querySelectorAll('.datepicker:not(.no-autoinit)'), - Dropdown: context.querySelectorAll('.dropdown-trigger:not(.no-autoinit)'), - Materialbox: context.querySelectorAll('.materialboxed:not(.no-autoinit)'), - Modal: context.querySelectorAll('.modal:not(.no-autoinit)'), - Parallax: context.querySelectorAll('.parallax:not(.no-autoinit)'), - Pushpin: context.querySelectorAll('.pushpin:not(.no-autoinit)'), - ScrollSpy: context.querySelectorAll('.scrollspy:not(.no-autoinit)'), - FormSelect: context.querySelectorAll('select:not(.no-autoinit)'), - Sidenav: context.querySelectorAll('.sidenav:not(.no-autoinit)'), - Tabs: context.querySelectorAll('.tabs:not(.no-autoinit)'), - TapTarget: context.querySelectorAll('.tap-target:not(.no-autoinit)'), - Timepicker: context.querySelectorAll('.timepicker:not(.no-autoinit)'), - Tooltip: context.querySelectorAll('.tooltipped:not(.no-autoinit)'), - FloatingActionButton: context.querySelectorAll('.fixed-action-btn:not(.no-autoinit)') - }; - Autocomplete.init(registry.Autocomplete, options?.Autocomplete ?? {}); - Cards.init(registry.Cards, options?.Cards ?? {}); - Carousel.init(registry.Carousel, options?.Carousel ?? {}); - Chips.init(registry.Chips, options?.Chips ?? {}); - Collapsible.init(registry.Collapsible, options?.Collapsible ?? {}); - Datepicker.init(registry.Datepicker, options?.Datepicker ?? {}); - Dropdown.init(registry.Dropdown, options?.Dropdown ?? {}); - Materialbox.init(registry.Materialbox, options?.Materialbox ?? {}); - Modal.init(registry.Modal, options?.Modal ?? {}); - Parallax.init(registry.Parallax, options?.Parallax ?? {}); - Pushpin.init(registry.Pushpin, options?.Pushpin ?? {}); - ScrollSpy.init(registry.ScrollSpy, options?.ScrollSpy ?? {}); - FormSelect.init(registry.FormSelect, options?.FormSelect ?? {}); - Sidenav.init(registry.Sidenav, options?.Sidenav ?? {}); - Tabs.init(registry.Tabs, options?.Tabs ?? {}); - TapTarget.init(registry.TapTarget, options?.TapTarget ?? {}); - Timepicker.init(registry.Timepicker, options?.Timepicker ?? {}); - Tooltip.init(registry.Tooltip, options?.Tooltip ?? {}); - FloatingActionButton.init(registry.FloatingActionButton, options?.FloatingActionButton ?? {}); -} -// Init -if (typeof document !== 'undefined') { - document.addEventListener('keydown', Utils.docHandleKeydown, true); - document.addEventListener('keyup', Utils.docHandleKeyup, true); - document.addEventListener('focus', Utils.docHandleFocus, true); - document.addEventListener('blur', Utils.docHandleBlur, true); -} -Forms.Init(); -Chips.Init(); -Waves.Init(); -Range.Init(); -Cards.Init(); - -export { AutoInit, Autocomplete, Cards, Carousel, CharacterCounter, Chips, Collapsible, Datepicker, Dropdown, FloatingActionButton, FormSelect, Forms, Materialbox, Modal, Parallax, Pushpin, Range, ScrollSpy, Sidenav, Slider, Tabs, TapTarget, Timepicker, Toast, Tooltip, Waves, version }; From cf1a585eb25b165a547ee9a85e584d90810888de Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 8 Jul 2026 12:27:52 +0200 Subject: [PATCH 06/60] fix: ignore dist files --- .gitignore | 2 +- package.json | 2 +- tsconfig.json | 22 ++++------------------ 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index b39fc3fbd4..dc7e1dfa30 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,7 @@ node_modules/ # Ignore lock yarn.lock -dist/*.zip +dist/**/* *storybook.log storybook-static diff --git a/package.json b/package.json index e5e6d6c6e4..e7b3c23099 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "dist/css", "dist/js", "sass/**/*.scss", - "components", + "components/**/*.ts", "LICENSE" ], "overrides": { diff --git a/tsconfig.json b/tsconfig.json index 702a550266..a9eac4ce45 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,8 @@ -{ +{ "compilerOptions": { - //"outDir": "./dist", - //"emitDecoratorMetadata": true, - //"experimentalDecorators": true, "module": "ESNext", "moduleResolution": "Bundler", - "target": "ES2022", - //"skipLibCheck": true, - //"esModuleInterop": true, - //"resolveJsonModule": true, - //"sourceMap": true, - //"composite": true, - //"declaration": true, - //"declarationMap": true, + "target": "ES2022" }, - "include": [ - "src", - "src/**/*", - "rollup.config.ts" - ] -} \ No newline at end of file + "include": ["src", "src/**/*", "rollup.config.ts"] +} From a9c1f0d742cc589a9696199fcc3e23edf97b2d8b Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Tue, 21 Jul 2026 16:05:46 +0200 Subject: [PATCH 07/60] refactor: remove unused code --- components/atomic/component.mjs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/components/atomic/component.mjs b/components/atomic/component.mjs index dfb82d5ec9..3bd47173e9 100644 --- a/components/atomic/component.mjs +++ b/components/atomic/component.mjs @@ -1,12 +1,3 @@ -// function escapeHTML(str) { -// return str -// .replaceAll('&', '&') -// .replaceAll('<', '<') -// .replaceAll('>', '>') -// .replaceAll('"', '"') -// .replaceAll("'", '''); -// } - class Component { #tagname; #children; From f9e8d2f5d2a6bd97dc18fcd9e51a2dcf526dace4 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Fri, 24 Jul 2026 09:15:00 +0200 Subject: [PATCH 08/60] refactor: group exports and remove put too simple classes in place --- components/tooltip/tooltip.ts | 8 +- package-lock.json | 485 ++++++++++++++++------------------ package.json | 3 +- src/bounding.ts | 6 - src/characterCounter.ts | 6 +- src/dockedDisplayPlugin.ts | 30 ++- src/edges.ts | 6 - src/modalDisplayPlugin.ts | 48 ++-- src/parallax.ts | 6 +- src/pushpin.ts | 6 +- src/scrollspy.ts | 6 +- src/tapTarget.ts | 6 +- src/utils.ts | 17 +- 13 files changed, 318 insertions(+), 315 deletions(-) delete mode 100644 src/bounding.ts delete mode 100644 src/edges.ts diff --git a/components/tooltip/tooltip.ts b/components/tooltip/tooltip.ts index e7233ceeb8..dab16f88c8 100644 --- a/components/tooltip/tooltip.ts +++ b/components/tooltip/tooltip.ts @@ -1,9 +1,15 @@ import { Utils } from '../../src/utils'; -import { Bounding } from '../../src/bounding'; import { Component, BaseOptions, InitElements, MElement } from '../../src/component'; // TODO: Rewrite this using popover and js only +class Bounding { + left: number; // left offset coordinate + top: number; + width: number; + height: number; +} + export type TooltipPosition = 'top' | 'right' | 'bottom' | 'left'; export interface TooltipOptions extends BaseOptions { diff --git a/package-lock.json b/package-lock.json index 6e7f6b9449..22ced04da6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -543,9 +543,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, "license": "MIT", "dependencies": { @@ -626,9 +626,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -638,7 +638,7 @@ "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", + "js-yaml": "^4.3.0", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, @@ -650,9 +650,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -687,9 +687,9 @@ } }, "node_modules/@fontsource/material-icons": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@fontsource/material-icons/-/material-icons-5.2.7.tgz", - "integrity": "sha512-crPmK0L34lPGmS5GSGLasKpRGQzl95SxMsLM+QhBHPgR9uxSsyI5CUTb0cgoMpjtR+Bf1bC9QOe6pavoybbBwg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/material-icons/-/material-icons-5.3.0.tgz", + "integrity": "sha512-nCpzNTsS5KpIqWijK259rPOTaZXNJlRfTiVRDNguKwfSdoZL/O9zIvPs+3K2eeRrNW+fVJWMO+n3JQoi9DN9Tw==", "dev": true, "license": "OFL-1.1", "funding": { @@ -898,9 +898,9 @@ } }, "node_modules/@parcel/watcher": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", - "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz", + "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -909,7 +909,7 @@ "detect-libc": "^2.0.3", "is-glob": "^4.0.3", "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">= 10.0.0" @@ -919,25 +919,24 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", - "@parcel/watcher-darwin-x64": "2.5.6", - "@parcel/watcher-freebsd-x64": "2.5.6", - "@parcel/watcher-linux-arm-glibc": "2.5.6", - "@parcel/watcher-linux-arm-musl": "2.5.6", - "@parcel/watcher-linux-arm64-glibc": "2.5.6", - "@parcel/watcher-linux-arm64-musl": "2.5.6", - "@parcel/watcher-linux-x64-glibc": "2.5.6", - "@parcel/watcher-linux-x64-musl": "2.5.6", - "@parcel/watcher-win32-arm64": "2.5.6", - "@parcel/watcher-win32-ia32": "2.5.6", - "@parcel/watcher-win32-x64": "2.5.6" + "@parcel/watcher-android-arm64": "2.6.0", + "@parcel/watcher-darwin-arm64": "2.6.0", + "@parcel/watcher-darwin-x64": "2.6.0", + "@parcel/watcher-freebsd-x64": "2.6.0", + "@parcel/watcher-linux-arm-glibc": "2.6.0", + "@parcel/watcher-linux-arm-musl": "2.6.0", + "@parcel/watcher-linux-arm64-glibc": "2.6.0", + "@parcel/watcher-linux-arm64-musl": "2.6.0", + "@parcel/watcher-linux-x64-glibc": "2.6.0", + "@parcel/watcher-linux-x64-musl": "2.6.0", + "@parcel/watcher-win32-arm64": "2.6.0", + "@parcel/watcher-win32-x64": "2.6.0" } }, "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", - "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz", + "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==", "cpu": [ "arm64" ], @@ -956,9 +955,9 @@ } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", - "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz", + "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==", "cpu": [ "arm64" ], @@ -977,9 +976,9 @@ } }, "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", - "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz", + "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==", "cpu": [ "x64" ], @@ -998,9 +997,9 @@ } }, "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", - "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz", + "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==", "cpu": [ "x64" ], @@ -1019,9 +1018,9 @@ } }, "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", - "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz", + "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==", "cpu": [ "arm" ], @@ -1043,9 +1042,9 @@ } }, "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", - "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz", + "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==", "cpu": [ "arm" ], @@ -1067,9 +1066,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", - "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz", + "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==", "cpu": [ "arm64" ], @@ -1091,9 +1090,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", - "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz", + "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==", "cpu": [ "arm64" ], @@ -1115,9 +1114,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", - "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz", + "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==", "cpu": [ "x64" ], @@ -1139,9 +1138,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", - "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz", + "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==", "cpu": [ "x64" ], @@ -1163,9 +1162,9 @@ } }, "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", - "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz", + "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==", "cpu": [ "arm64" ], @@ -1183,31 +1182,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", - "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", - "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz", + "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==", "cpu": [ "x64" ], @@ -2019,17 +1997,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.1.tgz", - "integrity": "sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/type-utils": "8.62.1", - "@typescript-eslint/utils": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -2042,15 +2020,15 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.62.1", + "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", "dev": true, "license": "MIT", "engines": { @@ -2058,16 +2036,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz", - "integrity": "sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "engines": { @@ -2083,14 +2061,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz", - "integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.62.1", - "@typescript-eslint/types": "^8.62.1", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "engines": { @@ -2105,14 +2083,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz", - "integrity": "sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2123,9 +2101,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz", - "integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "license": "MIT", "engines": { @@ -2140,15 +2118,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz", - "integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/utils": "8.62.1", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2165,9 +2143,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz", - "integrity": "sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, "license": "MIT", "engines": { @@ -2179,16 +2157,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz", - "integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.62.1", - "@typescript-eslint/tsconfig-utils": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/visitor-keys": "8.62.1", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2217,16 +2195,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { @@ -2246,16 +2224,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.1.tgz", - "integrity": "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.62.1", - "@typescript-eslint/types": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2270,13 +2248,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz", - "integrity": "sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.1", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2697,9 +2675,9 @@ "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz", - "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==", + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz", + "integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==", "dev": true, "funding": [ { @@ -2717,8 +2695,8 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.28.4", - "caniuse-lite": "^1.0.30001799", + "browserslist": "^4.28.6", + "caniuse-lite": "^1.0.30001806", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" @@ -2771,9 +2749,9 @@ } }, "node_modules/bare-fs": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.3.tgz", - "integrity": "sha512-xRgplks8SvcKkdlv2M6Z2LZmRsmqd+x0nXXGXeMEjwdibj1HSDrlnqBRLeYdMvsgCox7Bq0e+DHwfczOfsn6IA==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.4.tgz", + "integrity": "sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2795,25 +2773,12 @@ } } }, - "node_modules/bare-os": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.3.tgz", - "integrity": "sha512-fF4Q7QsyKVF5Rj0qvI8BgUNjqzC2JvQlpTaPLjVJVxYVUX5Zr9un+y3w1HmA4nNKdFmRBT8z/WmrjvXzXVerKQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "bare": ">=1.14.0" - } - }, "node_modules/bare-path": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.1.tgz", - "integrity": "sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.1.tgz", + "integrity": "sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bare-os": "^3.0.1" - } + "license": "Apache-2.0" }, "node_modules/bare-stream": { "version": "2.13.3", @@ -2844,9 +2809,9 @@ } }, "node_modules/bare-url": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.5.tgz", - "integrity": "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.6.tgz", + "integrity": "sha512-iQxPClE07hETVpbRoX7JXX3v/ZQViCxe/SYCxylRLzdEx1xJAufPptfiOqR8tqiCtmbtMDANKWszzjLu1PMAZQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2875,9 +2840,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.42", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", - "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.1.tgz", + "integrity": "sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2901,9 +2866,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.5", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", - "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", + "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", "dev": true, "license": "MIT", "dependencies": { @@ -2943,9 +2908,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", - "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -2967,9 +2932,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz", - "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "dev": true, "funding": [ { @@ -2987,10 +2952,10 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.38", - "caniuse-lite": "^1.0.30001799", - "electron-to-chromium": "^1.5.376", - "node-releases": "^2.0.48", + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { @@ -3094,9 +3059,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001802", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001802.tgz", - "integrity": "sha512-vmv8ub2xwTNmljSKf82mtCk5JH7hC+YgzLj3P5zotvA0tPQ9016tdNNOG8WRca1IxOnhSsivB+J0z5FeE5LOUw==", + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", "dev": true, "funding": [ { @@ -3497,9 +3462,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.387", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.387.tgz", - "integrity": "sha512-TaxwufTFDufvPEoXdhwVrA3UdFWBeWGkYoJ1K8ldF1xe6gKfth6iRNS5lTQ5JPNOHdGQm8PT1QYKUqFLCiUefQ==", + "version": "1.5.396", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.396.tgz", + "integrity": "sha512-yHiw2Y3C3H9U6TMbOfoWK/BPreiOPXRfTWPBwQBoZG6/8TB6eOPnsy5oaRYuatR7Fw2SJ4kKforgufeo7fq0EQ==", "dev": true, "license": "ISC" }, @@ -3541,9 +3506,9 @@ } }, "node_modules/es-module-lexer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.0.tgz", - "integrity": "sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", "dev": true, "license": "MIT" }, @@ -3646,9 +3611,9 @@ } }, "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -3657,8 +3622,8 @@ "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -4061,9 +4026,9 @@ } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, "license": "MIT", "dependencies": { @@ -4164,9 +4129,9 @@ } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.3.tgz", + "integrity": "sha512-/zipXxyO6rGvuNGDiULY9MvEGSkb2gaG4GGH4ygMi0ZZzyMHdUZBmntJmx5x1G2VuPytCwGN4xsJP6cw+sK+vQ==", "dev": true, "license": "ISC" }, @@ -4343,9 +4308,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, "license": "MIT", "dependencies": { @@ -5229,9 +5194,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -5273,9 +5238,9 @@ "optional": true }, "node_modules/node-releases": { - "version": "2.0.50", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", - "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", "dev": true, "license": "MIT", "engines": { @@ -5312,9 +5277,9 @@ } }, "node_modules/obug": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", - "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", @@ -5562,9 +5527,9 @@ } }, "node_modules/postcss": { - "version": "8.5.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", - "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "version": "8.5.22", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.22.tgz", + "integrity": "sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==", "dev": true, "funding": [ { @@ -5582,7 +5547,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -5743,9 +5708,9 @@ } }, "node_modules/react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "dev": true, "license": "MIT", "engines": { @@ -5753,16 +5718,16 @@ } }, "node_modules/react-dom": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "dev": true, "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.7" + "react": "^19.2.8" } }, "node_modules/react-is": { @@ -5801,9 +5766,9 @@ } }, "node_modules/readdir-glob/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, "license": "MIT", "dependencies": { @@ -6079,9 +6044,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.101.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", - "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", + "version": "1.101.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.7.tgz", + "integrity": "sha512-cDeUYU0dhwKVbpYg/ppsjyuoddxYhWlJOkRoI7+/iZsaSp7iowWDfm+tL2HcUafedWBDvbf/+hx0QRgKG4JSHA==", "dev": true, "license": "MIT", "dependencies": { @@ -6107,9 +6072,9 @@ "license": "MIT" }, "node_modules/selenium-webdriver": { - "version": "4.45.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.45.0.tgz", - "integrity": "sha512-Cb2nqvJiwXVOtRTCYHX9D1FJR5+Ls7aL3Nev0t6n4CpXsQ//YGiiUmSCbvTDDeLtbV85SZ46qmLab4SIYKXWRw==", + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.46.0.tgz", + "integrity": "sha512-UlTkgnx9y+bf3QxFsrgUyMqC2oy1Yf+qcOs7xIC/XfsUPv/ow7Sicx6SJ7AeOn2/Z+xF1M8SLqyn983wipI82w==", "dev": true, "funding": [ { @@ -6415,9 +6380,9 @@ } }, "node_modules/std-env": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", - "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, @@ -6652,9 +6617,9 @@ } }, "node_modules/terser": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", - "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.0.tgz", + "integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6846,16 +6811,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.62.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.1.tgz", - "integrity": "sha512-vymnnM5g0AKQDSAyfP12nMIBvgwgA42syg74kkuZ4x1VuTzwQKwc5h9rGxeShCjny5o+zWAb6OEoz7XLgrIkIw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.62.1", - "@typescript-eslint/parser": "8.62.1", - "@typescript-eslint/typescript-estree": "8.62.1", - "@typescript-eslint/utils": "8.62.1" + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7883,9 +7848,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index e7b3c23099..5f62bfcff7 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,7 @@ "vitest": "^4.0.18" }, "files": [ - "dist/css", - "dist/js", + "dist", "sass/**/*.scss", "components/**/*.ts", "LICENSE" diff --git a/src/bounding.ts b/src/bounding.ts deleted file mode 100644 index e73cf2315a..0000000000 --- a/src/bounding.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class Bounding { - left: number; // left offset coordinate - top: number; - width: number; - height: number; -} diff --git a/src/characterCounter.ts b/src/characterCounter.ts index c238c4fabe..fe658e42e9 100644 --- a/src/characterCounter.ts +++ b/src/characterCounter.ts @@ -1,12 +1,12 @@ import { Component, InitElements, MElement } from './component'; -export interface BaseOptions {} +interface BaseOptions {} const _defaults = Object.freeze({}); type InputElement = HTMLInputElement | HTMLTextAreaElement; -export class CharacterCounter extends Component { +class CharacterCounter extends Component { declare el: InputElement; /** Stores the reference to the counter HTML element. */ counterEl: HTMLSpanElement; @@ -119,3 +119,5 @@ export class CharacterCounter extends Component { } } } + +export { BaseOptions, CharacterCounter }; diff --git a/src/dockedDisplayPlugin.ts b/src/dockedDisplayPlugin.ts index cd1dd2fb32..77bfe9c440 100644 --- a/src/dockedDisplayPlugin.ts +++ b/src/dockedDisplayPlugin.ts @@ -1,6 +1,6 @@ import { Utils } from './utils'; -export interface DockedDisplayPluginOptions { +interface DockedDisplayPluginOptions { /** * Margin between element and docked container */ @@ -20,7 +20,7 @@ export interface DockedDisplayPluginOptions { /** * Title element. */ - title: HTMLElement|null, + title: HTMLElement | null; /** * On open callback. */ @@ -41,7 +41,7 @@ const _defaults: DockedDisplayPluginOptions = { onClose: null }; -export class DockedDisplayPlugin { +class DockedDisplayPlugin { private readonly el: HTMLElement; private readonly container: HTMLDivElement; private options: Partial; @@ -63,15 +63,19 @@ export class DockedDisplayPlugin { this.container.append(container); el.parentElement.append(this.container); - document.addEventListener('click', (e) => { - if ( - this.visible && - !(this.el === e.target) && - !(e.target).closest('.display-docked') - ) { - this.hide(); - } - }, true); + document.addEventListener( + 'click', + (e) => { + if ( + this.visible && + !(this.el === e.target) && + !(e.target).closest('.display-docked') + ) { + this.hide(); + } + }, + true + ); } /** @@ -132,3 +136,5 @@ export class DockedDisplayPlugin { }, 100); }; } + +export { DockedDisplayPluginOptions, DockedDisplayPlugin }; diff --git a/src/edges.ts b/src/edges.ts deleted file mode 100644 index fd76390e79..0000000000 --- a/src/edges.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class Edges { - top: boolean; // If the top edge was exceeded - right: boolean; // If the right edge was exceeded - bottom: boolean; // If the bottom edge was exceeded - left: boolean; // If the left edge was exceeded -} diff --git a/src/modalDisplayPlugin.ts b/src/modalDisplayPlugin.ts index 9d030998a4..9524600232 100644 --- a/src/modalDisplayPlugin.ts +++ b/src/modalDisplayPlugin.ts @@ -1,12 +1,12 @@ -export interface ModalDisplayPluginOptions { +interface ModalDisplayPluginOptions { /** * Classes to add on modal container. */ - classList: string[], + classList: string[]; /** * Title element. */ - title: HTMLElement|null, + title: HTMLElement | null; /** * On open callback. */ @@ -21,27 +21,31 @@ const _defaults: ModalDisplayPluginOptions = { classList: ['modal'], title: null, onOpen: null, - onClose: null, -} + onClose: null +}; -export class ModalDisplayPlugin { +class ModalDisplayPlugin { private readonly el: HTMLElement; private readonly container: HTMLDialogElement; private options: Partial; private visible: boolean; footer: HTMLElement; - constructor(el: HTMLElement, container: HTMLElement, options: Partial) { + constructor( + el: HTMLElement, + container: HTMLElement, + options: Partial + ) { this.el = el; this.options = { ..._defaults, - ...options, + ...options }; this.container = document.createElement('dialog'); this.container.classList.add('modal', 'display-modal', this.options.classList.join(' ')); - if(options.title) { + if (options.title) { const modalHeader = document.createElement('div'); modalHeader.classList.add('modal-header'); modalHeader.append(options.title); @@ -59,11 +63,19 @@ export class ModalDisplayPlugin { document.body.append(this.container); - document.addEventListener('click', (e) => { - if (this.visible && !(this.el === e.target) && !((e.target).closest('.display-modal'))) { - this.hide(); - } - }, true); + document.addEventListener( + 'click', + (e) => { + if ( + this.visible && + !(this.el === e.target) && + !(e.target).closest('.display-modal') + ) { + this.hide(); + } + }, + true + ); } /** @@ -72,7 +84,11 @@ export class ModalDisplayPlugin { * @param container HTMLElement to be positioned * @param options Plugin options */ - static init(el: HTMLElement, container: HTMLElement, options?: Partial): ModalDisplayPlugin { + static init( + el: HTMLElement, + container: HTMLElement, + options?: Partial + ): ModalDisplayPlugin { return new ModalDisplayPlugin(el, container, options); } @@ -98,3 +114,5 @@ export class ModalDisplayPlugin { }, 10); }; } + +export { ModalDisplayPluginOptions, ModalDisplayPlugin }; diff --git a/src/parallax.ts b/src/parallax.ts index d34f0fc820..c672ff80c8 100644 --- a/src/parallax.ts +++ b/src/parallax.ts @@ -1,7 +1,7 @@ import { Utils } from './utils'; import { Component, BaseOptions, InitElements, MElement } from './component'; -export interface ParallaxOptions extends BaseOptions { +interface ParallaxOptions extends BaseOptions { /** * The minimum width of the screen, in pixels, where the parallax functionality starts working. * @default 0 @@ -13,7 +13,7 @@ const _defaults: ParallaxOptions = { responsiveThreshold: 0 // breakpoint for swipeable }; -export class Parallax extends Component { +class Parallax extends Component { private _enabled: boolean; private _img: HTMLImageElement; static _parallaxes: Parallax[] = []; @@ -149,3 +149,5 @@ export class Parallax extends Component { } } } + +export { ParallaxOptions, Parallax }; diff --git a/src/pushpin.ts b/src/pushpin.ts index 2c0c73572c..31e8b75488 100644 --- a/src/pushpin.ts +++ b/src/pushpin.ts @@ -1,7 +1,7 @@ import { Utils } from './utils'; import { Component, BaseOptions, InitElements, MElement } from './component'; -export interface PushpinOptions extends BaseOptions { +interface PushpinOptions extends BaseOptions { /** * The distance in pixels from the top of the page where * the element becomes fixed. @@ -34,7 +34,7 @@ const _defaults = { onPositionChange: null }; -export class Pushpin extends Component { +class Pushpin extends Component { static _pushpins: Pushpin[]; originalOffset: number; @@ -166,3 +166,5 @@ export class Pushpin extends Component { Pushpin._pushpins = []; } } + +export { PushpinOptions, Pushpin }; diff --git a/src/scrollspy.ts b/src/scrollspy.ts index 47b7e58cbc..be66c7ab5a 100644 --- a/src/scrollspy.ts +++ b/src/scrollspy.ts @@ -1,7 +1,7 @@ import { Utils } from './utils'; import { Component, BaseOptions, InitElements, MElement } from './component'; -export interface ScrollSpyOptions extends BaseOptions { +interface ScrollSpyOptions extends BaseOptions { /** * Throttle of scroll handler. * @default 100 @@ -50,7 +50,7 @@ const _defaults: ScrollSpyOptions = { animationDuration: null }; -export class ScrollSpy extends Component { +class ScrollSpy extends Component { static _elements: ScrollSpy[]; static _count: number; static _increment: number; @@ -349,3 +349,5 @@ export class ScrollSpy extends Component { ScrollSpy._ticks = 0; } } + +export { ScrollSpyOptions, ScrollSpy }; diff --git a/src/tapTarget.ts b/src/tapTarget.ts index 6aabed3a1d..bebc99cd84 100644 --- a/src/tapTarget.ts +++ b/src/tapTarget.ts @@ -1,7 +1,7 @@ import { Utils } from './utils'; import { Component, BaseOptions, InitElements, MElement, Openable } from './component'; -export interface TapTargetOptions extends BaseOptions { +interface TapTargetOptions extends BaseOptions { /** * Callback function called when Tap Target is opened. * @default null @@ -19,7 +19,7 @@ const _defaults: TapTargetOptions = { onClose: null }; -export class TapTarget extends Component implements Openable { +class TapTarget extends Component implements Openable { /** * If the tap target is open. */ @@ -313,3 +313,5 @@ export class TapTarget extends Component implements Openable { TapTarget._taptargets = []; } } + +export { TapTargetOptions, TapTarget }; diff --git a/src/utils.ts b/src/utils.ts index c3d5ad7ec0..3d417eb04a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,16 @@ -import { Edges } from './edges'; -import { Bounding } from './bounding'; +class Edges { + top: boolean; // If the top edge was exceeded + right: boolean; // If the right edge was exceeded + bottom: boolean; // If the bottom edge was exceeded + left: boolean; // If the left edge was exceeded +} + +class Bounding { + left: number; // left offset coordinate + top: number; + width: number; + height: number; +} /** * Class with utilitary functions for global usage. @@ -379,7 +390,7 @@ export class Utils { container.style.top = newCoordinates.y + 'px'; container.style.left = newCoordinates.x + 'px'; - return {x: xMovement, y: yMovement}; + return { x: xMovement, y: yMovement }; } static _repositionWithinScreen( From 1a5382a31a408c0463542f9c088bb6f60218f4c4 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Fri, 24 Jul 2026 14:49:57 +0200 Subject: [PATCH 09/60] fix(chips): improve style and blog example --- components/atomic/component.mjs | 30 +++++++++++---- components/atomic/page.mjs | 6 +++ components/chip/chip.mjs | 15 +++++++- components/chip/chips.css | 18 ++++++++- examples/compile.sh | 10 +++-- examples/html/blog.html | 27 ++++++++++++-- examples/html/landingpage.html | 3 +- examples/html/portfolio.html | 3 +- examples/src/blog.js | 65 ++++++++++++++++++++++++++++----- examples/src/landingpage.js | 4 +- examples/src/portfolio.js | 4 +- index.html | 10 ++--- package.json | 11 ++---- 13 files changed, 159 insertions(+), 47 deletions(-) diff --git a/components/atomic/component.mjs b/components/atomic/component.mjs index 3bd47173e9..fce33b6f50 100644 --- a/components/atomic/component.mjs +++ b/components/atomic/component.mjs @@ -2,13 +2,15 @@ class Component { #tagname; #children; #classNames; + #attributes; constructor(options) { this.#tagname = 'div'; + this.#attributes = {}; this.#children = []; this.#classNames = []; - if (typeof options === 'object' && options.children) { - // Tree Nodes + + if (typeof options === 'object' && options !== null && options.children) { if (typeof options.children === 'string') { this.#children = options.children; return; @@ -17,7 +19,6 @@ class Component { kids.forEach((c) => this.addChild(c)); return; } - // Text or numeric this.#children = options; } @@ -38,6 +39,11 @@ class Component { return this; } + setAttribute(key, value) { + this.#attributes[key] = value; + return this; + } + addClassname(name) { this.#classNames.push(name); return this; @@ -46,13 +52,21 @@ class Component { toHTML() { const classAttr = this.#classNames.length === 0 ? '' : ' class="' + this.#classNames.join(' ') + '"'; - if (typeof this.#children === 'object' && Array.isArray(this.#children)) - return `<${this.#tagname}${classAttr}>${this.#children.map((child) => child.toHTML()).join('')}`; - // string or number - return `<${this.#tagname}${classAttr}>${this.#children}`; + + const attrEntries = Object.entries(this.#attributes); + const otherAttrs = + attrEntries.length === 0 + ? '' + : ' ' + attrEntries.map(([key, val]) => `${key}="${val}"`).join(' '); + + if (Array.isArray(this.#children)) { + const innerHTML = this.#children.map((child) => child.toHTML()).join(''); + return `<${this.#tagname}${classAttr}${otherAttrs}>${innerHTML}`; + } + + return `<${this.#tagname}${classAttr}${otherAttrs}>${this.#children ?? ''}`; } - // TODO: remove here toDOM() { const template = document.createElement('template'); template.innerHTML = this.toHTML(); diff --git a/components/atomic/page.mjs b/components/atomic/page.mjs index 01a13a9f08..a6d30ebcb1 100644 --- a/components/atomic/page.mjs +++ b/components/atomic/page.mjs @@ -4,6 +4,7 @@ class Page extends Component { #title; #metaDescription; #styleList = []; + #css = []; constructor(options) { super(options); @@ -15,6 +16,10 @@ class Page extends Component { this.#styleList.push(url); return this; } + addStyle(css) { + this.#css.push(css); + return this; + } addJavascriptUrl() { return this; } @@ -35,6 +40,7 @@ class Page extends Component { (s) => `` ) .join('')} + ${this.#css.map((s) => ``).join('\n')} diff --git a/components/chip/chip.mjs b/components/chip/chip.mjs index 1c63e8dece..f1f9be017e 100644 --- a/components/chip/chip.mjs +++ b/components/chip/chip.mjs @@ -8,6 +8,12 @@ class Chip extends Component { constructor(options) { super(options); this.addClassname('chip'); + this.setAttribute('tabindex', '0'); + if (options.name) this.#text = options.name; + if (options.href) { + this.setTagName('a'); + this.setAttribute('href', options.href); + } } setId(id) { @@ -34,4 +40,11 @@ class Chip extends Component { } } -export { Chip }; +class AssistChip extends Chip { + constructor(options) { + super(options); + this.addClassname('assist-chip'); // TODO: remove classname chip + } +} + +export { Chip, AssistChip }; diff --git a/components/chip/chips.css b/components/chip/chips.css index a35d635e0f..6ca974c8d8 100644 --- a/components/chip/chips.css +++ b/components/chip/chips.css @@ -4,7 +4,7 @@ --padding: 8px; color: var(--md-sys-color-on-surface-variant); - background-color: rgba(0, 0, 0, 0.09); + background-color: var(--md-sys-color-surface); display: inline-flex; white-space: nowrap; gap: 8px; @@ -19,6 +19,16 @@ user-select: none; vertical-align: top; } + +.chip:hover { + background-color: color-mix( + in srgb, + var(--md-sys-color-surface), + var(--md-sys-color-surface-tint) 16% + ); + color: var(--md-sys-color-on-surface); +} + .chip:focus { outline: none; background-color: var(--md-sys-color-primary); @@ -124,3 +134,9 @@ font-size: 0.8rem; transform: translateY(-140%); } + +/*------------------------------------------ Assist Chip */ +.assist-chip { + background-color: var(--md-sys-color-surface); + outline: 1px solid var(--md-sys-color-outline); +} diff --git a/examples/compile.sh b/examples/compile.sh index 2f1c6f9df7..7e368cda5b 100755 --- a/examples/compile.sh +++ b/examples/compile.sh @@ -1,4 +1,8 @@ #!/bin/bash -node src/blog.js > html/blog.html -node src/landingpage.js > html/landingpage.html -node src/portfolio.js > html/portfolio.html + +pwd +cd examples + +node ./src/blog.js > ./html/blog.html +node ./src/landingpage.js > ./html/landingpage.html +node ./src/portfolio.js > ./html/portfolio.html diff --git a/examples/html/blog.html b/examples/html/blog.html index cb2bccb2ef..c38360f3a9 100644 --- a/examples/html/blog.html +++ b/examples/html/blog.html @@ -1,11 +1,32 @@ - My Blog - + Materialize Web Blog + +
-

Blog

This is a featured Post
2 or 3-column masonry grid showing article thumbnails, titles, and publication dates
[object Object]This is a test Landingpage. ok it can produce nested html too...
+

Materialize Web Blog

Home > Articles > Crafting Sleek, Responsive Interfaces with MaterializeWeb
+

01/01/2026 posted by Daniel

+

Crafting Sleek, Responsive Interfaces with MaterializeWeb

+

In the fast-evolving landscape of web development, building clean, responsive, and intuitive user interfaces remains a top priority. While major CSS frameworks like Bootstrap have long dominated the scene, MaterializeWeb—the community-driven evolution of MaterializeCSS—offers a refreshing design philosophy anchored directly in Google’s Material Design principles.

+

What is MaterializeWeb?

+

MaterializeWeb is an open-source, responsive front-end framework designed to streamline frontend development. Inspired by physical tactile materials like paper and ink, Materialize translates real-world physics into digital interfaces. It packages complex design concepts into ready-to-use HTML, CSS, and JavaScript components, allowing developers to create consistent, polished web applications with minimal overhead.

+

Key Features and Benefits

+
    +
  • Material Design Aesthetic: Out of the box, MaterializeWeb provides realistic shadow depths, smooth motion transitions, and responsive ripple effects that make UI elements feel interactive and tactile.
  • +
  • Community-Driven Continuity: Originally created as MaterializeCSS, the framework was actively adapted and maintained as MaterializeWeb by an open-source developer community, ensuring modern web standard compliance, security updates, and active bug fixes.
  • +
  • Flexible Grid & Utilities: Featuring a robust CSS grid system, flexbox support, and utility classes for typography, color palettes, and spacing, setting up complex responsive layouts takes minutes rather than hours.
  • +
  • Rich Component Suite: Developers get access to pre-styled components, including floating action buttons (FABs), navigation bars, dynamic modals, toast notifications, cards, and interactive carousels.
  • +
+

Why Choose It for Your Next Project?

+

If you want your web applications to mirror the sleek, unified visual identity of modern mobile apps without spending weeks writing custom styles, MaterializeWeb is an outstanding choice. It strikes an ideal balance between aesthetic polish and developer efficiency, making it perfect for rapid prototyping and production-ready sites alike.

+

Give MaterializeWeb a try on your next project to experience how effortless modern visual design can be!

2 or 3-column masonry grid showing article thumbnails, titles, and publication dates
This is a test Landingpage. ok it can produce nested html too...
Or you can go to the Portfolio
Sidebar or navigation dropdowns ("Tech," "Lifestyle")
diff --git a/examples/html/landingpage.html b/examples/html/landingpage.html index 513f0356d2..275bce5c28 100644 --- a/examples/html/landingpage.html +++ b/examples/html/landingpage.html @@ -1,6 +1,7 @@ My Landingpage - + + diff --git a/examples/html/portfolio.html b/examples/html/portfolio.html index 986b7330e7..a4add8a257 100644 --- a/examples/html/portfolio.html +++ b/examples/html/portfolio.html @@ -1,6 +1,7 @@ My Portfolio - + + diff --git a/examples/src/blog.js b/examples/src/blog.js index 4dac5d63e1..44a2cfa74b 100644 --- a/examples/src/blog.js +++ b/examples/src/blog.js @@ -2,28 +2,69 @@ import { Text } from '../../components/atomic/atomic.mjs'; import { Component } from '../../components/atomic/component.mjs'; import { Container, Page } from '../../components/atomic/page.mjs'; import { Button } from '../../components/button/button.mjs'; +import { AssistChip } from '../../components/chip/chip.mjs'; -class Link extends Component { +// class Link extends Component { +// constructor(options) { +// super(options); +// this.setTagName('a'); +// //this.setAttribute('href', options.href); +// } +// } + +class BlogArticle extends Component { constructor(options) { super(options); - this.setTagName('a'); - //this.setAttribute('href', options.href); + this.setTagName('article'); + this.addClassname('card').addClassname('p-5'); } } +const myArticle = new BlogArticle(` +

01/01/2026 posted by Daniel

+

Crafting Sleek, Responsive Interfaces with MaterializeWeb

+

In the fast-evolving landscape of web development, building clean, responsive, and intuitive user interfaces remains a top priority. While major CSS frameworks like Bootstrap have long dominated the scene, MaterializeWeb—the community-driven evolution of MaterializeCSS—offers a refreshing design philosophy anchored directly in Google’s Material Design principles.

+

What is MaterializeWeb?

+

MaterializeWeb is an open-source, responsive front-end framework designed to streamline frontend development. Inspired by physical tactile materials like paper and ink, Materialize translates real-world physics into digital interfaces. It packages complex design concepts into ready-to-use HTML, CSS, and JavaScript components, allowing developers to create consistent, polished web applications with minimal overhead.

+

Key Features and Benefits

+
    +
  • Material Design Aesthetic: Out of the box, MaterializeWeb provides realistic shadow depths, smooth motion transitions, and responsive ripple effects that make UI elements feel interactive and tactile.
  • +
  • Community-Driven Continuity: Originally created as MaterializeCSS, the framework was actively adapted and maintained as MaterializeWeb by an open-source developer community, ensuring modern web standard compliance, security updates, and active bug fixes.
  • +
  • Flexible Grid & Utilities: Featuring a robust CSS grid system, flexbox support, and utility classes for typography, color palettes, and spacing, setting up complex responsive layouts takes minutes rather than hours.
  • +
  • Rich Component Suite: Developers get access to pre-styled components, including floating action buttons (FABs), navigation bars, dynamic modals, toast notifications, cards, and interactive carousels.
  • +
+

Why Choose It for Your Next Project?

+

If you want your web applications to mirror the sleek, unified visual identity of modern mobile apps without spending weeks writing custom styles, MaterializeWeb is an outstanding choice. It strikes an ideal balance between aesthetic polish and developer efficiency, making it perfect for rapid prototyping and production-ready sites alike.

+

Give MaterializeWeb a try on your next project to experience how effortless modern visual design can be!

`); + const blogPage = new Page({ - title: 'My Blog', + title: 'Materialize Web Blog', description: 'This is a custom blog', keywords: 'News sites, personal journals, niche resource hubs, and content creators.', children: [ - new Container({ children: new Text('Blog').setTagName('h1') }), - new Container({ children: 'This is a featured Post' }).addClassname('py-5'), + new Container({ + children: new Text('Materialize Web Blog').setTagName('p').addClassname('py-3') + }), + new Container({ + children: [ + new AssistChip({ href: './landingpage.html', name: 'Visit Landingpage' }), + new AssistChip({ href: './portfolio.html', name: 'Visit Porfolio' }) + ] + }) + .addClassname('g-2') + .addClassname('row'), + + // TODO: use Breadcrumb Component + new Container({ + children: 'Home > Articles > Crafting Sleek, Responsive Interfaces with MaterializeWeb' + }).addClassname('py-5'), + + myArticle, new Container({ children: '2 or 3-column masonry grid showing article thumbnails, titles, and publication dates' }).addClassname('py-5'), new Button({ children: 'Call to action' }), - new Link({ href: '.landingpage.html' }), new Text( `This is a test Landingpage. ok it can produce nested html too...
Or you can go to the Portfolio` @@ -32,9 +73,13 @@ const blogPage = new Page({ children: 'Sidebar or navigation dropdowns ("Tech," "Lifestyle")' }).addClassname('py-5') ] -}).addStyleUrl( - 'https://cdn.jsdelivr.net/npm/@materializecss/materialize@latest/dist/css/materialize.min.css' -); +}).addStyleUrl('/dist/css/materialize.css') + .addStyle(`article { font-family: Times; line-height: 1.25; } + h1 { font-size: 2.75em; } + h2 { font-size: 2em; } + h3 { font-size: 1.5em; } + p, li { font-size: 1.2em; } + `); const html = blogPage.toHTML(); console.log(html); diff --git a/examples/src/landingpage.js b/examples/src/landingpage.js index c9a5881e1e..e287d503b5 100644 --- a/examples/src/landingpage.js +++ b/examples/src/landingpage.js @@ -19,9 +19,7 @@ const landingPage = new Page({ You can also checkout the Blog`), new Container('Hello, this is my landing page!').addClassname('pt-5') ] -}).addStyleUrl( - 'https://cdn.jsdelivr.net/npm/@materializecss/materialize@latest/dist/css/materialize.min.css' -); +}).addStyleUrl('/dist/css/materialize.css'); const html = landingPage.toHTML(); console.log(html); diff --git a/examples/src/portfolio.js b/examples/src/portfolio.js index dd62ac97f5..2021201619 100644 --- a/examples/src/portfolio.js +++ b/examples/src/portfolio.js @@ -23,9 +23,7 @@ const portfolioPage = new Page({ .setColumns(2) .addClassname('py-5') ] -}).addStyleUrl( - 'https://cdn.jsdelivr.net/npm/@materializecss/materialize@latest/dist/css/materialize.min.css' -); +}).addStyleUrl('/dist/css/materialize.css'); const html = portfolioPage.toHTML(); console.log(html); diff --git a/index.html b/index.html index 81fb6a6486..9cf2563e1a 100644 --- a/index.html +++ b/index.html @@ -29,13 +29,13 @@
-

Test

-

This is for quick testing purposes. The files are used from dist directory.

- -
+

Examples

+

For quick testing purposes. The files are used from dist directory. + Generate server side html or render on client. Be in control and decide.

+ 👉 Visit Blog +
Appbar
-
Textfields
diff --git a/package.json b/package.json index 5f62bfcff7..f6f7515644 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "type": "git", "url": "git://github.com/materializecss/materialize.git" }, + "type": "module", "bugs": { "url": "https://github.com/materializecss/materialize/issues" }, @@ -40,11 +41,12 @@ "lint": "eslint .", "test": "jasmine-browser-runner runSpecs --config=jasmine.json", "build": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript", + "build-storybook": "storybook build", + "build-examples": "examples/compile.sh", "release": "npm run lint && npm run build -- --environment BUILD:release && node compress.mjs", "preversion": "npm run lint && npm test", "version": "npm run build -- --environment BUILD:release && node compress.mjs && git add .", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build", "demo": "live-server", "vitest": "vitest" }, @@ -54,13 +56,6 @@ "git add" ] }, - "browserslist": [ - "last 2 versions", - "Chrome >= 30", - "Firefox >= 30", - "Safari >= 8" - ], - "engine": "node >= 6", "dependencies": { "normalize.css": "^8.0.1" }, From a67bbc31f4c68f12fb710240cbb5d5df72df8dcc Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Mon, 27 Jul 2026 16:31:52 +0200 Subject: [PATCH 10/60] feat(chip): transition to vitest --- .../chip/{chipsSpec.js => __chipsSpec.js} | 0 components/chip/chip.test.mjs | 10 - components/chip/chip.test.ts | 224 ++++++++++++++++++ package-lock.json | 73 ++++++ package.json | 1 + 5 files changed, 298 insertions(+), 10 deletions(-) rename components/chip/{chipsSpec.js => __chipsSpec.js} (100%) delete mode 100644 components/chip/chip.test.mjs create mode 100644 components/chip/chip.test.ts diff --git a/components/chip/chipsSpec.js b/components/chip/__chipsSpec.js similarity index 100% rename from components/chip/chipsSpec.js rename to components/chip/__chipsSpec.js diff --git a/components/chip/chip.test.mjs b/components/chip/chip.test.mjs deleted file mode 100644 index 89013d0456..0000000000 --- a/components/chip/chip.test.mjs +++ /dev/null @@ -1,10 +0,0 @@ -import { describe, expect, test } from 'vitest'; -import { Chip } from './chip.mjs'; - -describe('chip', () => { - test('create html', () => { - const chip = new Chip().setText('John Doe'); - //console.log(list.toHTML()); - expect(chip.toHTML()).toContain('John'); - }); -}); diff --git a/components/chip/chip.test.ts b/components/chip/chip.test.ts new file mode 100644 index 0000000000..862a2c9cdd --- /dev/null +++ b/components/chip/chip.test.ts @@ -0,0 +1,224 @@ +// @vitest-environment happy-dom +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { Chips } from './chips.ts'; + +// Attach M to both global and window contexts +const globalM = { Chips }; +global.M = globalM; +if (typeof window !== 'undefined') { + (window as any).M = globalM; +} + +// Utility helper to replace done() timeouts with async/await +const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + +// Event helpers to dispatch native DOM events compatible with Happy DOM +const keydown = (element: Element, keyCode: number) => { + element.dispatchEvent( + new KeyboardEvent('keydown', { + keyCode: keyCode, + which: keyCode, + key: keyCode === 13 ? 'Enter' : '', + code: keyCode === 13 ? 'Enter' : '', + bubbles: true, + cancelable: true + }) + ); +}; + +const click = (element: Element) => { + element.dispatchEvent( + new MouseEvent('click', { + bubbles: true, + cancelable: true + }) + ); +}; + +describe('Chips', () => { + const fixture = `
+
+
+
+
+
`; + + beforeEach(() => { + // Inject fixture HTML directly into the DOM + document.body.innerHTML = fixture; + + // Initialize Components + (global.M as any).Chips.init(document.querySelector('.chips')); + (global.M as any).Chips.init(document.querySelector('.chips-initial'), { + data: [ + { id: 12, text: 'Apple' }, + { id: 13, text: 'Microsoft' }, + { + id: 42, + text: 'Google', + image: + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' + } + ] + }); + (global.M as any).Chips.init(document.querySelector('.chips.input-field'), { + allowUserInput: true + }); + (global.M as any).Chips.init(document.querySelector('.chips-initial.input-field'), { + allowUserInput: true, + data: [ + { id: 12, text: 'Apple' }, + { id: 13, text: 'Microsoft' }, + { + id: 42, + text: 'Google', + image: + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' + } + ] + }); + (global.M as any).Chips.init(document.querySelector('.chips-placeholder.input-field'), { + allowUserInput: true, + placeholder: 'Enter a tag', + secondaryPlaceholder: '+Tag' + }); + (global.M as any).Chips.init(document.querySelector('.chips-autocomplete.input-field'), { + allowUserInput: true, + autocompleteOptions: { + data: [ + { id: 12, text: 'Apple' }, + { id: 13, text: 'Microsoft' }, + { id: 42, text: 'Google' } + ] + } + }); + }); + + afterEach(() => { + // Clean up DOM after each test + document.body.innerHTML = ''; + }); + + describe('chips plugin', () => { + let chips: HTMLElement | null, + chipsUserInput: HTMLElement | null, + input: HTMLInputElement | NodeListOf | null; + + it('should work with multiple initializations', () => { + chips = document.querySelector('.chips'); + (global.M as any).Chips.init(chips); + (global.M as any).Chips.init(chips); + (global.M as any).Chips.init(chips); + chipsUserInput = document.querySelector('.chips.input-field'); + (global.M as any).Chips.init(chips, { allowUserInput: true }); + + const inputs = chipsUserInput?.querySelectorAll('input'); + expect(inputs?.length, 'Should dynamically generate chips structure.').toBe(1); + }); + + it('should be able to add chip', async () => { + chips = document.querySelector('.chips.input-field'); + const inputEl = chips?.querySelector('input') as HTMLInputElement; + inputEl.value = 'one'; + keydown(inputEl, 13); + + await delay(100); + + const numChips = chips?.querySelectorAll('.chip').length; + const oneChip = chips?.querySelector('.chip') as HTMLElement; + expect(numChips, 'one chip should have been added').toBe(1); + + for (let i = oneChip.children.length - 1; i >= 0; i--) { + oneChip.children[i].remove(); + } + expect(oneChip.innerText, 'the chip should have value "one"').toBe('one'); + }); + + it('should be able to delete chip', async () => { + chips = document.querySelector('.chips.chips-initial.input-field'); + let numChips = chips?.querySelectorAll('.chip').length; + expect(numChips, '3 initial chips should have been added').toBe(3); + + const chipCloseButton = chips?.querySelectorAll('.chip .close'); + expect(chipCloseButton?.length, 'expected all chips to have close button').toBe(3); + + if (chipCloseButton && chipCloseButton[0]) { + click(chipCloseButton[0]); + } + + await delay(100); + + numChips = chips?.querySelectorAll('.chip').length; + expect(numChips, 'one chip should have been deleted').toBe(2); + }); + + it('should have working callbacks', async () => { + chips = document.querySelector('.chips.input-field'); + let chipWasAdded = false; + let chipAddedElem: any = null; + let chipSelect = false; + let chipSelected: any = null; + let chipDelete = false; + let chipDeleted: any = null; + + (global.M as any).Chips.init(chips, { + allowUserInput: true, + data: [{ id: 'One' }, { id: 'Two' }, { id: 'Three' }], + onChipAdd: (_chipsEl: any, chipEl: any) => { + chipAddedElem = chipEl; + chipWasAdded = true; + }, + onChipSelect: (_chipsEl: any, chipEl: any) => { + chipSelected = chipEl; + chipSelect = true; + }, + onChipDelete: (_chipsEl: any, chipEl: any) => { + chipDeleted = chipEl; + chipDelete = true; + } + }); + + const inputEl = chips?.querySelector('input') as HTMLInputElement; + inputEl.value = 'Four'; + expect(chipWasAdded, 'callback not yet fired').toBe(false); + expect(chipSelect, 'callback not yet fired').toBe(false); + expect(chipDelete, 'callback not yet fired').toBe(false); + + keydown(inputEl, 13); + + await delay(100); + + expect(chipWasAdded, 'add callback fired').toBe(true); + expect( + chipAddedElem.childNodes[0].nodeValue, + 'add callback provides correct chip element' + ).toBe('Four'); + + const chipList = chips?.querySelectorAll('.chip'); + if (chipList && chipList[1]) { + click(chipList[1]); + } + + await delay(100); + + expect(chipSelect, 'select callback fired').toBe(true); + expect( + chipSelected.childNodes[0].nodeValue, + 'select callback provides correct chip element' + ).toBe('Two'); + + const closeList = chips?.querySelectorAll('.close'); + if (closeList && closeList[2]) { + click(closeList[2]); + } + + await delay(100); + + expect(chipDelete, 'delete callback fired').toBe(true); + expect( + chipDeleted.childNodes[0].nodeValue, + 'delete callback provides correct chip element' + ).toBe('Three'); + }); + }); +}); diff --git a/package-lock.json b/package-lock.json index 22ced04da6..0423c09f7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "autoprefixer": "^10.4.21", "eslint": "^9.10.0", "eslint-plugin-storybook": "^9.0.12", + "happy-dom": "^20.11.1", "jasmine": "^5.1.0", "jasmine-browser-runner": "^2.5.0", "jasmine-core": "^5.2.0", @@ -1996,6 +1997,23 @@ "csstype": "^3.2.2" } }, + "node_modules/@types/whatwg-mimetype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", + "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.65.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", @@ -3007,6 +3025,19 @@ "dev": true, "license": "MIT" }, + "node_modules/buffer-image-size": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/buffer-image-size/-/buffer-image-size-0.6.4.tgz", + "integrity": "sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -3485,6 +3516,19 @@ "node": ">= 0.8" } }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -4408,6 +4452,25 @@ "dev": true, "license": "ISC" }, + "node_modules/happy-dom": { + "version": "20.11.1", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.11.1.tgz", + "integrity": "sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": ">=20.0.0", + "@types/whatwg-mimetype": "^3.0.2", + "@types/ws": "^8.18.1", + "buffer-image-size": "^0.6.4", + "entities": "^7.0.1", + "whatwg-mimetype": "^3.0.0", + "ws": "^8.21.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7712,6 +7775,16 @@ "dev": true, "license": "MIT" }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index f6f7515644..83b5e3d22e 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "autoprefixer": "^10.4.21", "eslint": "^9.10.0", "eslint-plugin-storybook": "^9.0.12", + "happy-dom": "^20.11.1", "jasmine": "^5.1.0", "jasmine-browser-runner": "^2.5.0", "jasmine-core": "^5.2.0", From 688bd6d6d383a15094b1322e545185f46558e0bf Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Mon, 10 Aug 2026 10:41:38 +0200 Subject: [PATCH 11/60] fix: update dependencies --- package-lock.json | 858 +++++++++++++++++++++++++--------------------- 1 file changed, 461 insertions(+), 397 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0423c09f7e..5c48c3f4ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,28 +59,29 @@ "license": "MIT" }, "node_modules/@babel/code-frame": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", - "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-8.0.0.tgz", + "integrity": "sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.29.7", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" + "@babel/helper-validator-identifier": "^8.0.0", + "js-tokens": "^10.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^22.18.0 || >=24.11.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-8.0.4.tgz", + "integrity": "sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==", "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": ">=6.9.0" + "node": "^22.18.0 || >=24.11.0" } }, "node_modules/@babel/runtime": { @@ -860,6 +861,26 @@ "react": ">=16" } }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1289,9 +1310,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", - "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", "cpu": [ "arm" ], @@ -1303,9 +1324,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", - "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", "cpu": [ "arm64" ], @@ -1317,9 +1338,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", - "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", "cpu": [ "arm64" ], @@ -1331,9 +1352,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", - "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", "cpu": [ "x64" ], @@ -1345,9 +1366,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", - "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", "cpu": [ "arm64" ], @@ -1359,9 +1380,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", - "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", "cpu": [ "x64" ], @@ -1373,9 +1394,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", - "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", "cpu": [ "arm" ], @@ -1390,9 +1411,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", - "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", "cpu": [ "arm" ], @@ -1407,9 +1428,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", - "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", "cpu": [ "arm64" ], @@ -1424,9 +1445,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", - "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", "cpu": [ "arm64" ], @@ -1441,9 +1462,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", - "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", "cpu": [ "loong64" ], @@ -1458,9 +1479,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", - "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", "cpu": [ "loong64" ], @@ -1475,9 +1496,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", - "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", "cpu": [ "ppc64" ], @@ -1492,9 +1513,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", - "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", "cpu": [ "ppc64" ], @@ -1509,9 +1530,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", - "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", "cpu": [ "riscv64" ], @@ -1526,9 +1547,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", - "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", "cpu": [ "riscv64" ], @@ -1543,9 +1564,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", - "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", "cpu": [ "s390x" ], @@ -1560,9 +1581,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", - "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", "cpu": [ "x64" ], @@ -1577,9 +1598,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", - "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", "cpu": [ "x64" ], @@ -1594,9 +1615,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", - "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", "cpu": [ "x64" ], @@ -1608,9 +1629,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", - "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", "cpu": [ "arm64" ], @@ -1622,9 +1643,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", - "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", "cpu": [ "arm64" ], @@ -1636,9 +1657,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", - "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", "cpu": [ "ia32" ], @@ -1650,9 +1671,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", - "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", "cpu": [ "x64" ], @@ -1664,9 +1685,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", - "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", "cpu": [ "x64" ], @@ -1860,6 +1881,41 @@ "node": ">=18" } }, + "node_modules/@testing-library/dom/node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@testing-library/dom/node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@testing-library/dom/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@testing-library/jest-dom": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", @@ -1888,9 +1944,9 @@ "license": "MIT" }, "node_modules/@testing-library/user-event": { - "version": "14.6.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", - "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "version": "14.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.3.tgz", + "integrity": "sha512-6dBq67jT8lE+JTE8Exm02Kt6ze43hz1jdiSpSJwtTZiT1xQQ6b7nZYTTQ9njdArdU8XklOwaDp/AbT/eYSKF4g==", "dev": true, "license": "MIT", "engines": { @@ -1987,9 +2043,9 @@ } }, "node_modules/@types/react": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", - "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", + "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", "dev": true, "license": "MIT", "peer": true, @@ -2015,17 +2071,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", - "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz", + "integrity": "sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.65.0", - "@typescript-eslint/type-utils": "8.65.0", - "@typescript-eslint/utils": "8.65.0", - "@typescript-eslint/visitor-keys": "8.65.0", + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/type-utils": "8.66.0", + "@typescript-eslint/utils": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -2038,7 +2094,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.65.0", + "@typescript-eslint/parser": "^8.66.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -2054,16 +2110,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", - "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.66.0.tgz", + "integrity": "sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.65.0", - "@typescript-eslint/types": "8.65.0", - "@typescript-eslint/typescript-estree": "8.65.0", - "@typescript-eslint/visitor-keys": "8.65.0", + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", "debug": "^4.4.3" }, "engines": { @@ -2079,14 +2135,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", - "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.66.0.tgz", + "integrity": "sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.65.0", - "@typescript-eslint/types": "^8.65.0", + "@typescript-eslint/tsconfig-utils": "^8.66.0", + "@typescript-eslint/types": "^8.66.0", "debug": "^4.4.3" }, "engines": { @@ -2101,14 +2157,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", - "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz", + "integrity": "sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.65.0", - "@typescript-eslint/visitor-keys": "8.65.0" + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2119,9 +2175,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", - "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz", + "integrity": "sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==", "dev": true, "license": "MIT", "engines": { @@ -2136,15 +2192,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", - "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz", + "integrity": "sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.65.0", - "@typescript-eslint/typescript-estree": "8.65.0", - "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/utils": "8.66.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2161,9 +2217,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", - "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.66.0.tgz", + "integrity": "sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==", "dev": true, "license": "MIT", "engines": { @@ -2175,16 +2231,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", - "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz", + "integrity": "sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.65.0", - "@typescript-eslint/tsconfig-utils": "8.65.0", - "@typescript-eslint/types": "8.65.0", - "@typescript-eslint/visitor-keys": "8.65.0", + "@typescript-eslint/project-service": "8.66.0", + "@typescript-eslint/tsconfig-utils": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2213,9 +2269,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", - "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { @@ -2226,13 +2282,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -2242,16 +2298,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", - "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.66.0.tgz", + "integrity": "sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.65.0", - "@typescript-eslint/types": "8.65.0", - "@typescript-eslint/typescript-estree": "8.65.0" + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2266,13 +2322,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", - "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz", + "integrity": "sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/types": "8.66.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2406,9 +2462,9 @@ } }, "node_modules/@vitest/runner/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "dev": true, "license": "MIT", "engines": { @@ -2460,9 +2516,9 @@ } }, "node_modules/@vitest/snapshot/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "dev": true, "license": "MIT", "engines": { @@ -2525,9 +2581,9 @@ } }, "node_modules/acorn": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", - "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, "license": "MIT", "bin": { @@ -2767,9 +2823,9 @@ } }, "node_modules/bare-fs": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.4.tgz", - "integrity": "sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.0.tgz", + "integrity": "sha512-fM+MhCvdQhZ7NV6S95a07gPSqjIYKn6mFaXfx266wN3ajZGl/+1AzH+ubkXQ0fFZvOe2nk9VHkzdYkQE5zMV3Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2780,7 +2836,7 @@ "fast-fifo": "^1.3.2" }, "engines": { - "bare": ">=1.16.0" + "bare": ">=1.28.0" }, "peerDependencies": { "bare-buffer": "*" @@ -2827,9 +2883,9 @@ } }, "node_modules/bare-url": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.6.tgz", - "integrity": "sha512-iQxPClE07hETVpbRoX7JXX3v/ZQViCxe/SYCxylRLzdEx1xJAufPptfiOqR8tqiCtmbtMDANKWszzjLu1PMAZQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.5.1.tgz", + "integrity": "sha512-cD5ciQuKlx+eumTCfqbfiL+fhQm+dHbVNB/cX4+d+I/nx4JsVop9VoFEPAs5RJ6I84QR6bZIBjpd2kjDOYeWcg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2858,9 +2914,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.1.tgz", - "integrity": "sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A==", + "version": "2.11.13", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz", + "integrity": "sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2926,9 +2982,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -2950,9 +3006,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", - "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", "dev": true, "funding": [ { @@ -2970,11 +3026,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.44", - "caniuse-lite": "^1.0.30001806", - "electron-to-chromium": "^1.5.393", - "node-releases": "^2.0.51", - "update-browserslist-db": "^1.2.3" + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" @@ -3090,9 +3146,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001806", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", - "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", "dev": true, "funding": [ { @@ -3493,9 +3549,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.396", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.396.tgz", - "integrity": "sha512-yHiw2Y3C3H9U6TMbOfoWK/BPreiOPXRfTWPBwQBoZG6/8TB6eOPnsy5oaRYuatR7Fw2SJ4kKforgufeo7fq0EQ==", + "version": "1.5.403", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz", + "integrity": "sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==", "dev": true, "license": "ISC" }, @@ -4070,9 +4126,9 @@ } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", - "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -4173,9 +4229,9 @@ } }, "node_modules/flatted": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.3.tgz", - "integrity": "sha512-/zipXxyO6rGvuNGDiULY9MvEGSkb2gaG4GGH4ygMi0ZZzyMHdUZBmntJmx5x1G2VuPytCwGN4xsJP6cw+sK+vQ==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", "dev": true, "license": "ISC" }, @@ -4352,9 +4408,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", - "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -4453,9 +4509,9 @@ "license": "ISC" }, "node_modules/happy-dom": { - "version": "20.11.1", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.11.1.tgz", - "integrity": "sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==", + "version": "20.11.2", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.11.2.tgz", + "integrity": "sha512-7MB+bJLkxu3SowAfBJbjW+c55kNz5tkR45gu2qzrxznezhLeN5YIlJbwUgSzlGc+qWoZ8Ykg71H5ezz69xixrw==", "dev": true, "license": "MIT", "dependencies": { @@ -4852,16 +4908,17 @@ "license": "MIT" }, "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/js-yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", - "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", "dev": true, "funding": [ { @@ -5257,9 +5314,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { @@ -5301,9 +5358,9 @@ "optional": true }, "node_modules/node-releases": { - "version": "2.0.51", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", - "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", "dev": true, "license": "MIT", "engines": { @@ -5590,9 +5647,9 @@ } }, "node_modules/postcss": { - "version": "8.5.22", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.22.tgz", - "integrity": "sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==", + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", "dev": true, "funding": [ { @@ -5610,7 +5667,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.16", + "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -5829,9 +5886,9 @@ } }, "node_modules/readdir-glob/node_modules/brace-expansion": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", - "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -5852,9 +5909,9 @@ } }, "node_modules/readdirp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", - "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", + "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==", "dev": true, "license": "MIT", "engines": { @@ -5866,9 +5923,9 @@ } }, "node_modules/recast": { - "version": "0.23.12", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.12.tgz", - "integrity": "sha512-dEWRjcINDu/F4l2dYx57ugBtD7HV9KXESyxhzw/MqWLeglJrsjJKqACPyUPg+6AF8mIgm+Zi0dZ3ACoIg+QtpA==", + "version": "0.23.20", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.20.tgz", + "integrity": "sha512-VtSf75pThDqsIUpdaYrTdQvkw10/+yP0i7+Cax7h+K9SRvYjrJURZcRlcHMrH6TMzV275Q8a2A8+G7y7W9zqsg==", "dev": true, "license": "MIT", "dependencies": { @@ -5879,7 +5936,7 @@ "tslib": "^2.0.1" }, "engines": { - "node": ">= 4" + "node": ">= 22" } }, "node_modules/redent": { @@ -5940,9 +5997,9 @@ } }, "node_modules/rollup": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", - "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", "dev": true, "license": "MIT", "dependencies": { @@ -5956,31 +6013,32 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.62.2", - "@rollup/rollup-android-arm64": "4.62.2", - "@rollup/rollup-darwin-arm64": "4.62.2", - "@rollup/rollup-darwin-x64": "4.62.2", - "@rollup/rollup-freebsd-arm64": "4.62.2", - "@rollup/rollup-freebsd-x64": "4.62.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", - "@rollup/rollup-linux-arm-musleabihf": "4.62.2", - "@rollup/rollup-linux-arm64-gnu": "4.62.2", - "@rollup/rollup-linux-arm64-musl": "4.62.2", - "@rollup/rollup-linux-loong64-gnu": "4.62.2", - "@rollup/rollup-linux-loong64-musl": "4.62.2", - "@rollup/rollup-linux-ppc64-gnu": "4.62.2", - "@rollup/rollup-linux-ppc64-musl": "4.62.2", - "@rollup/rollup-linux-riscv64-gnu": "4.62.2", - "@rollup/rollup-linux-riscv64-musl": "4.62.2", - "@rollup/rollup-linux-s390x-gnu": "4.62.2", - "@rollup/rollup-linux-x64-gnu": "4.62.2", - "@rollup/rollup-linux-x64-musl": "4.62.2", - "@rollup/rollup-openbsd-x64": "4.62.2", - "@rollup/rollup-openharmony-arm64": "4.62.2", - "@rollup/rollup-win32-arm64-msvc": "4.62.2", - "@rollup/rollup-win32-ia32-msvc": "4.62.2", - "@rollup/rollup-win32-x64-gnu": "4.62.2", - "@rollup/rollup-win32-x64-msvc": "4.62.2", + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", "fsevents": "~2.3.2" } }, @@ -6002,9 +6060,9 @@ } }, "node_modules/rollup-plugin-dts": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.4.1.tgz", - "integrity": "sha512-l//F3Zf7ID5GoOfLfD8kroBjQKEKpy1qfhtAdnpibFZMffPaylrg1CoDC2vGkPeTeyxUe4bVFCln2EFuL7IGGg==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.5.1.tgz", + "integrity": "sha512-jODTXp3H7MK/Ur/ErtsrQ0G1GvaCmc3du+y5pNrdBMf6d7HlL2Nd/N6TkEr+f75CkUj01zEoEd7y2elH0eHi1Q==", "dev": true, "license": "LGPL-3.0-only", "dependencies": { @@ -6020,11 +6078,17 @@ "url": "https://github.com/sponsors/Swatinem" }, "optionalDependencies": { - "@babel/code-frame": "^7.29.0" + "@babel/code-frame": "^8.0.0" }, "peerDependencies": { - "rollup": "^3.29.4 || ^4", - "typescript": "^4.5 || ^5.0 || ^6.0" + "@typescript/typescript6": "^6", + "rollup": "^3 || ^4", + "typescript": "^4.5 || ^5 || ^6 || ^7" + }, + "peerDependenciesMeta": { + "@typescript/typescript6": { + "optional": true + } } }, "node_modules/rollup-plugin-scss": { @@ -6107,9 +6171,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.101.7", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.7.tgz", - "integrity": "sha512-cDeUYU0dhwKVbpYg/ppsjyuoddxYhWlJOkRoI7+/iZsaSp7iowWDfm+tL2HcUafedWBDvbf/+hx0QRgKG4JSHA==", + "version": "1.102.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz", + "integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==", "dev": true, "license": "MIT", "dependencies": { @@ -6216,9 +6280,9 @@ "license": "MIT" }, "node_modules/serialize-javascript": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.7.tgz", - "integrity": "sha512-YAy8Od6KV+uuwUuU50np8fGB/Aues6Y0nAhA9y/hId74PlKUcme4pXcBD46NWKr1Q4osN/iseZ17YqO1XfmI8g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.0.tgz", + "integrity": "sha512-RNEqWOyhhUQYN9V1GfHwu9AR/g+NTciH6Z5u3/no6X3/w+04J2lVDL+svFQVXgXrEGBMG2puMVN3gq2SNGuTGw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -6680,9 +6744,9 @@ } }, "node_modules/terser": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.0.tgz", - "integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==", + "version": "5.49.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.2.tgz", + "integrity": "sha512-rGbJiKeQ4WDe3EXlDAIaQcwftVfv2Q8o1awFNfvXolJYKkb1AuZY1RTOmqx4LJXZENbWZA7eIsYGHuEzHsi1nQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6723,9 +6787,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", - "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", "dev": true, "license": "MIT", "engines": { @@ -6874,16 +6938,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.65.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", - "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", + "version": "8.66.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.66.0.tgz", + "integrity": "sha512-QlEbBPz/RuJ1XUHj29nm3t0F/O/cSlEnntozqPOYHnnTGAXFamnMBu5i9Vn6vhUPHGAjR+Vl+5J8vPN/BMUrJw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.65.0", - "@typescript-eslint/parser": "8.65.0", - "@typescript-eslint/typescript-estree": "8.65.0", - "@typescript-eslint/utils": "8.65.0" + "@typescript-eslint/eslint-plugin": "8.66.0", + "@typescript-eslint/parser": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/utils": "8.66.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6939,9 +7003,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz", + "integrity": "sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==", "dev": true, "funding": [ { @@ -7082,9 +7146,9 @@ } }, "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", "cpu": [ "ppc64" ], @@ -7099,9 +7163,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", "cpu": [ "arm" ], @@ -7116,9 +7180,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", "cpu": [ "arm64" ], @@ -7133,9 +7197,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", "cpu": [ "x64" ], @@ -7150,9 +7214,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", "cpu": [ "arm64" ], @@ -7167,9 +7231,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", "cpu": [ "x64" ], @@ -7184,9 +7248,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", "cpu": [ "arm64" ], @@ -7201,9 +7265,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", "cpu": [ "x64" ], @@ -7218,9 +7282,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", "cpu": [ "arm" ], @@ -7235,9 +7299,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", "cpu": [ "arm64" ], @@ -7252,9 +7316,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", "cpu": [ "ia32" ], @@ -7269,9 +7333,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", "cpu": [ "loong64" ], @@ -7286,9 +7350,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", "cpu": [ "mips64el" ], @@ -7303,9 +7367,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", "cpu": [ "ppc64" ], @@ -7320,9 +7384,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", "cpu": [ "riscv64" ], @@ -7337,9 +7401,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", "cpu": [ "s390x" ], @@ -7354,9 +7418,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", "cpu": [ "x64" ], @@ -7371,9 +7435,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", "cpu": [ "arm64" ], @@ -7388,9 +7452,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", "cpu": [ "x64" ], @@ -7405,9 +7469,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", "cpu": [ "arm64" ], @@ -7422,9 +7486,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", "cpu": [ "x64" ], @@ -7439,9 +7503,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", "cpu": [ "arm64" ], @@ -7456,9 +7520,9 @@ } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", "cpu": [ "x64" ], @@ -7473,9 +7537,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", "cpu": [ "arm64" ], @@ -7490,9 +7554,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", "cpu": [ "ia32" ], @@ -7507,9 +7571,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", "cpu": [ "x64" ], @@ -7524,9 +7588,9 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -7537,32 +7601,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" } }, "node_modules/vitest": { @@ -7759,9 +7823,9 @@ } }, "node_modules/vitest/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "dev": true, "license": "MIT", "engines": { @@ -7921,9 +7985,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.21.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", - "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", "dev": true, "license": "MIT", "engines": { From a2e779d30494e1373cfd990788da243b8313f0cd Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Mon, 10 Aug 2026 11:27:45 +0200 Subject: [PATCH 12/60] feat: add breadcrumb component --- components/breadcrumb/breadcrumb.mjs | 28 +++ components/chip/__chipsSpec.js | 165 -------------- components/collapsible/collapsible.test.ts | 234 ++++++++++++++++++++ components/collapsible/collapsible.ts | 6 +- components/collapsible/collapsibleSpec.js | 240 --------------------- components/collapsible/readme.md | 5 + components/navigation-drawer/sidenav.ts | 6 +- components/tabs/tabs.ts | 6 +- examples/html/blog.html | 8 +- examples/src/blog.js | 37 ++-- 10 files changed, 303 insertions(+), 432 deletions(-) create mode 100644 components/breadcrumb/breadcrumb.mjs delete mode 100644 components/chip/__chipsSpec.js create mode 100644 components/collapsible/collapsible.test.ts delete mode 100644 components/collapsible/collapsibleSpec.js create mode 100644 components/collapsible/readme.md diff --git a/components/breadcrumb/breadcrumb.mjs b/components/breadcrumb/breadcrumb.mjs new file mode 100644 index 0000000000..f4904d1a3b --- /dev/null +++ b/components/breadcrumb/breadcrumb.mjs @@ -0,0 +1,28 @@ +import { Component } from '../atomic/component.mjs'; + +class Breadcrumb extends Component { + #parts = []; + + constructor(options) { + super(options); + this.setTagName('nav'); + this.addClassname('breadcrumb-wrapper'); + } + + setCrumbs(parts) { + this.#parts = parts; + // todo: generate html + return this; + } + + toHTML() { + let html = ''; + html = this.#parts + .map((p, i) => `${p}`) + .join(''); + this.setChildren(html); + return super.toHTML(); + } +} + +export { Breadcrumb }; diff --git a/components/chip/__chipsSpec.js b/components/chip/__chipsSpec.js deleted file mode 100644 index d4a0cd6980..0000000000 --- a/components/chip/__chipsSpec.js +++ /dev/null @@ -1,165 +0,0 @@ -describe('Chips', () => { - const fixture = `
-
-
-
-
-
`; - - beforeEach(() => { - XloadHtml(fixture); - M.Chips.init(document.querySelector('.chips')); - M.Chips.init(document.querySelector('.chips-initial'), { - data: [ - { id: 12, text: 'Apple' }, - { id: 13, text: 'Microsoft' }, - { - id: 42, - text: 'Google', - image: - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' - } - ] - }); - M.Chips.init(document.querySelector('.chips.input-field'), { - allowUserInput: true - }); - M.Chips.init(document.querySelector('.chips-initial.input-field'), { - allowUserInput: true, - data: [ - { id: 12, text: 'Apple' }, - { id: 13, text: 'Microsoft' }, - { - id: 42, - text: 'Google', - image: - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' - } - ] - }); - M.Chips.init(document.querySelector('.chips-placeholder.input-field'), { - allowUserInput: true, - placeholder: 'Enter a tag', - secondaryPlaceholder: '+Tag' - }); - M.Chips.init(document.querySelector('.chips-autocomplete.input-field'), { - allowUserInput: true, - autocompleteOptions: { - data: [ - { id: 12, text: 'Apple' }, - { id: 13, text: 'Microsoft' }, - { id: 42, text: 'Google' } - ] - } - }); - }); - afterEach(() => XunloadFixtures()); - - describe('chips plugin', () => { - let chips, chipsUserInput, input; - - it('should work with multiple initializations', () => { - chips = document.querySelector('.chips'); - M.Chips.init(chips); - M.Chips.init(chips); - M.Chips.init(chips); - chipsUserInput = document.querySelector('.chips.input-field'); - M.Chips.init(chips, { allowUserInput: true }); - input = chipsUserInput.querySelectorAll('input'); - expect(input.length).toEqual(1, 'Should dynamically generate chips structure.'); - }); - - it('should be able to add chip', (done) => { - chips = document.querySelector('.chips.input-field'); - input = chips.querySelector('input'); - input.value = 'one'; - keydown(input, 13); - setTimeout(() => { - const numChips = chips.querySelectorAll('.chip').length; - const oneChip = chips.querySelector('.chip'); - expect(numChips).toEqual(1, 'one chip should have been added'); - for (let i = oneChip.children.length - 1; i >= 0; i--) { - oneChip.children[i].remove(); - } - expect(oneChip.innerText).toEqual('one', 'the chip should have value "one"'); - done(); - }, 100); // 400 - }); - - it('should be able to delete chip', (done) => { - chips = document.querySelector('.chips.chips-initial.input-field'); - let numChips = chips.querySelectorAll('.chip').length; - expect(numChips).toEqual(3, '3 initial chips should have been added'); - const chipCloseButton = chips.querySelectorAll('.chip .close'); - expect(chipCloseButton.length).toEqual(3, 'expected all chips to have close button'); - click(chipCloseButton[0]); - setTimeout(() => { - numChips = chips.querySelectorAll('.chip').length; - expect(numChips).toEqual(2, 'one chip should have been deleted'); - done(); - }, 100); // 400 - }); - - it('should have working callbacks', (done) => { - chips = document.querySelector('.chips.input-field'); - let chipWasAdded = false; - let chipAddedElem = null; - let chipSelect = false; - let chipSelected = null; - let chipDelete = false; - let chipDeleted = null; - - M.Chips.init(chips, { - allowUserInput: true, - data: [{ id: 'One' }, { id: 'Two' }, { id: 'Three' }], - onChipAdd: (chipsEl, chipEl) => { - chipAddedElem = chipEl; - chipWasAdded = true; - }, - onChipSelect: (chipsEl, chipEl) => { - chipSelected = chipEl; - chipSelect = true; - }, - onChipDelete: (chipsEl, chipEl) => { - chipDeleted = chipEl; - chipDelete = true; - } - }); - - input = chips.querySelector('input'); - input.value = 'Four'; - expect(chipWasAdded).toEqual(false, 'callback not yet fired'); - expect(chipSelect).toEqual(false, 'callback not yet fired'); - expect(chipDelete).toEqual(false, 'callback not yet fired'); - keydown(input, 13); - - setTimeout(() => { - expect(chipWasAdded).toEqual(true, 'add callback fired'); - expect(chipAddedElem.childNodes[0].nodeValue).toEqual( - 'Four', - 'add callback provides correct chip element' - ); - click(chips.querySelectorAll('.chip')[1]); - setTimeout(() => { - expect(chipSelect).toEqual(true, 'select callback fired'); - expect(chipSelected.childNodes[0].nodeValue).toEqual( - 'Two', - 'select callback provides correct chip element' - ); - click(chips.querySelectorAll('.close')[2]); - setTimeout(() => { - expect(chipDelete).toEqual(true, 'delete callback fired'); - expect(chipDeleted.childNodes[0].nodeValue).toEqual( - 'Three', - 'add callback provides correct chip element' - ); - done(); - }, 100); - }, 100); - }, 100); - }); - }); - - // describe("Chips autocomplete", () => { - // }); -}); diff --git a/components/collapsible/collapsible.test.ts b/components/collapsible/collapsible.test.ts new file mode 100644 index 0000000000..42e683f123 --- /dev/null +++ b/components/collapsible/collapsible.test.ts @@ -0,0 +1,234 @@ +// @vitest-environment happy-dom +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; +import { Collapsible } from './collapsible'; + +// Helper function to simulate clicking an element +function click(element: HTMLElement): void { + element.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true })); +} + +// Helper to handle timeouts cleanly with async/await +const wait = (ms: number): Promise => new Promise((resolve) => setTimeout(resolve, ms)); + +describe('Collapsible Plugin:', () => { + let collapsible: NodeListOf; + let accordion: HTMLElement; + let popout: HTMLElement; + let expandable: HTMLElement; + let expandablePreselect: HTMLElement; + + const fixture = ` + + +
    +
  • +
    filter_dramaFirst
    +

    Lorem ipsum dolor sit amet.

    +
  • +
  • +
    placeSecond
    +

    Lorem ipsum dolor sit amet.

    +
  • +
  • +
    whatshotThird
    +

    Lorem ipsum dolor sit amet.

    +
  • +
+ +
    +
  • +
    filter_dramaFirst
    +

    Lorem ipsum dolor sit amet.

    +
  • +
  • +
    placeSecond
    +

    Lorem ipsum dolor sit amet.

    +
  • +
  • +
    whatshotThird
    +

    Lorem ipsum dolor sit amet.

    +
  • +
+ +
    +
  • +
    filter_dramaFirst
    +

    Lorem ipsum dolor sit amet.

    +
  • +
  • +
    placeSecond
    +

    Lorem ipsum dolor sit amet.

    +
  • +
  • +
    whatshotThird
    +

    Lorem ipsum dolor sit amet.

    +
  • +
`; + + beforeEach(() => { + document.body.innerHTML = fixture; + + collapsible = document.querySelectorAll('.collapsible'); + expandable = document.querySelector('.expandable')!; + expandablePreselect = document.querySelector('.expandable-preselected')!; + accordion = document.querySelector('.accordion')!; + popout = document.querySelector('.popout')!; + + // Mock scrollHeight for virtual DOM environment + document.querySelectorAll('.collapsible-body').forEach((body) => { + Object.defineProperty(body, 'scrollHeight', { + configurable: true, + value: 100 + }); + }); + + Collapsible.init(Array.from(collapsible), { inDuration: 0, outDuration: 0 }); + Collapsible.init(expandable, { accordion: false, inDuration: 0, outDuration: 0 }); + Collapsible.init(expandablePreselect, { accordion: false, inDuration: 0, outDuration: 0 }); + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + describe('collapsible', () => { + it('should open all items, keeping all open', async () => { + const headers = expandable.querySelectorAll('.collapsible-header'); + const bodies = expandable.querySelectorAll('.collapsible-body'); + + // Collapsible body height should be 0 on start when hidden. + bodies.forEach((body) => { + expect(body.style.maxHeight).toBe(''); + }); + + // Open all items + headers.forEach((header) => click(header)); + + await wait(10); + + // Collapsible body height should be > 0 after being opened. + bodies.forEach((body) => { + expect(body.style.maxHeight).toBe('100px'); + }); + }); + + it('should allow preopened sections', () => { + const bodies = expandablePreselect.querySelectorAll('.collapsible-body'); + + bodies.forEach((body, i) => { + const headerLi = body.parentNode as HTMLElement; + + if (i === 1) { + expect(headerLi.classList.contains('active')).toBe(true); + expect(body.style.maxHeight).toBe('100px'); + } else { + expect(body.style.maxHeight).not.toBe('100px'); + } + }); + }); + + it('should open and close programmatically with callbacks', async () => { + const openCallback = vi.fn(); + const closeCallback = vi.fn(); + + Collapsible.init(expandable, { + accordion: false, + onOpenStart: openCallback, + onCloseStart: closeCallback, + inDuration: 0, + outDuration: 0 + }); + + const bodies = expandable.querySelectorAll('.collapsible-body'); + + expect(openCallback).not.toHaveBeenCalled(); + expect(closeCallback).not.toHaveBeenCalled(); + + bodies.forEach((body, i) => { + const instance = Collapsible.getInstance(body.closest('.collapsible') as HTMLElement); + instance.open(i); + }); + + expect(openCallback).toHaveBeenCalled(); + + await wait(10); + + bodies.forEach((body, i) => { + expect(body.style.maxHeight).toBe('100px'); + + const instance = Collapsible.getInstance(body.closest('.collapsible') as HTMLElement); + instance.close(i); + }); + + expect(closeCallback).toHaveBeenCalled(); + + await wait(10); + + bodies.forEach((body) => { + expect(body.style.maxHeight).toBe('0'); + }); + }); + }); + + describe('accordion', () => { + it('should open first and second items, keeping only second open', async () => { + const headers = accordion.querySelectorAll('.collapsible-header'); + const bodies = accordion.querySelectorAll('.collapsible-body'); + + expect(bodies[0].style.maxHeight).not.toBe('100px'); + expect(bodies[1].style.maxHeight).not.toBe('100px'); + + click(headers[0]); + + await wait(10); + + expect(bodies[0].style.maxHeight).toBe('100px'); + + click(headers[1]); + + await wait(10); + + expect(bodies[0].style.maxHeight).toBe('0'); + expect(bodies[1].style.maxHeight).toBe('100px'); + }); + }); + + describe('popout', () => { + it('should open first and popout', async () => { + const listItems = popout.querySelectorAll('li'); + const firstHeader = popout.querySelector('.collapsible-header')!; + const firstBody = popout.querySelector('.collapsible-body')!; + + expect(firstBody.style.maxHeight).not.toBe('100px'); + + // Closed popout items should have horizontal margins + listItems.forEach((li) => { + const style = getComputedStyle(li); + const marginLeft = parseInt(style.marginLeft || '0', 10); + const marginRight = parseInt(style.marginRight || '0', 10); + + expect(marginLeft).toBeGreaterThan(0); + expect(marginRight).toBeGreaterThan(0); + }); + + click(firstHeader); + + await wait(10); + + expect(firstBody.style.maxHeight).toBe('100px'); + }); + }); +}); diff --git a/components/collapsible/collapsible.ts b/components/collapsible/collapsible.ts index 7d9226ba7b..f74f953d42 100644 --- a/components/collapsible/collapsible.ts +++ b/components/collapsible/collapsible.ts @@ -1,7 +1,7 @@ import { Utils } from '../../src/utils'; import { Component, BaseOptions, InitElements, MElement } from '../../src/component'; -export interface CollapsibleOptions extends BaseOptions { +interface CollapsibleOptions extends BaseOptions { /** * If accordion versus collapsible. * @default true @@ -49,7 +49,7 @@ const _defaults: CollapsibleOptions = { outDuration: 300 }; -export class Collapsible extends Component { +class Collapsible extends Component { private _headers: HTMLElement[]; constructor(el: HTMLElement, options: Partial) { @@ -228,3 +228,5 @@ export class Collapsible extends Component { } }; } + +export { CollapsibleOptions, Collapsible }; diff --git a/components/collapsible/collapsibleSpec.js b/components/collapsible/collapsibleSpec.js deleted file mode 100644 index bc2e26d01b..0000000000 --- a/components/collapsible/collapsibleSpec.js +++ /dev/null @@ -1,240 +0,0 @@ -describe('Collapsible Plugin:', () => { - let collapsible, accordion, popout, expandable, expandablePreselect; - - const fixture = ` -
    -
  • -
    filter_dramaFirst
    -

    Lorem ipsum dolor sit amet.

    -
  • -
  • -
    placeSecond
    -

    Lorem ipsum dolor sit amet.

    -
  • -
  • -
    whatshotThird
    -

    Lorem ipsum dolor sit amet.

    -
  • -
- - -
    -
  • -
    filter_dramaFirst
    -

    Lorem ipsum dolor sit amet.

    -
  • -
  • -
    placeSecond
    -

    Lorem ipsum dolor sit amet.

    -
  • -
  • -
    whatshotThird
    -

    Lorem ipsum dolor sit amet.

    -
  • -
- -
    -
  • -
    filter_dramaFirst
    -

    Lorem ipsum dolor sit amet.

    -
  • -
  • -
    placeSecond
    -

    Lorem ipsum dolor sit amet.

    -
  • -
  • -
    whatshotThird
    -

    Lorem ipsum dolor sit amet.

    -
  • -
`; - - beforeEach(() => { - XloadHtml(fixture); - collapsible = document.querySelectorAll('.collapsible'); - expandable = document.querySelector('.expandable'); - expandablePreselect = document.querySelector('.expandable-preselected'); - accordion = document.querySelector('.accordion'); - popout = document.querySelector('.popout'); - M.Collapsible.init(collapsible, { inDuration: 0, outDuration: 0 }); - M.Collapsible.init(expandable, { accordion: false, inDuration: 0, outDuration: 0 }); - M.Collapsible.init(expandablePreselect, { accordion: false, inDuration: 0, outDuration: 0 }); - }); - - afterEach(() => XunloadFixtures()); - - describe('collapsible', () => { - it('should open all items, keeping all open', (done) => { - // Collapsible body height should be 0 on start when hidden. - const headers = expandable.querySelectorAll('.collapsible-header'); - const bodies = expandable.querySelectorAll('.collapsible-body'); - for (let i = 0; i < bodies.length; i++) { - expect(bodies[i]).hasMaxHeightZero( - 'because collapsible bodies should be hidden initially.' - ); - //TODO replace with alternative for deprecated jasmine-jquery - } - // Collapsible body height should be > 0 after being opened. - for (let i = 0; i < headers.length; i++) { - click(headers[i]); - } - setTimeout(() => { - for (let i = 0; i < bodies.length; i++) { - expect(bodies[i]).notHasMaxHeightZero( - 'because collapsible bodies not visible after being opened.' - ); //TODO replace with alternative for deprecated jasmine-jquery - } - done(); - }, 10); - }); - - it('should allow preopened sections', () => { - const bodies = expandablePreselect.querySelectorAll('.collapsible-body'); - for (let i = 0; i < bodies.length; i++) { - const headerLi = bodies[i].parentNode; - if (i === 1) { - expect(headerLi).toHaveClass( - 'active', - 'because collapsible header should have active class to be preselected.' - ); //TODO replace with alternative for deprecated jasmine-jquery - expect(bodies[i]).notHasMaxHeightZero( - 'because collapsible bodies should be visible if preselected.' - ); //TODO replace with alternative for deprecated jasmine-jquery - } else { - expect(bodies[i]).hasMaxHeightZero( - 'because collapsible bodies should be hidden initially.' - ); //TODO replace with alternative for deprecated jasmine-jquery - } - } - }); - - it('should open and close programmatically with callbacks', (done) => { - let openCallback = false; - let closeCallback = false; - M.Collapsible.init(expandable, { - accordion: false, - onOpenStart: () => { - openCallback = true; - }, - onCloseStart: () => { - closeCallback = true; - }, - inDuration: 0, - outDuration: 0 - }); - const bodies = expandable.querySelectorAll('.collapsible-body'); - expect(openCallback).toEqual(false, 'because open callback not yet fired'); - expect(closeCallback).toEqual(false, 'because close callback not yet fired'); - for (let i = 0; i < bodies.length; i++) { - //TODO replace with alternative for deprecated jasmine-jquery - expect(bodies[i]).hasMaxHeightZero( - 'because collapsible bodies should be hidden initially.' - ); - const collapsibleInstance = M.Collapsible.getInstance(bodies[i].parentNode.parentNode); - collapsibleInstance.open(i); - } - expect(openCallback).toEqual(true, 'because open callback fired'); - setTimeout(() => { - for (let i = 0; i < bodies.length; i++) { - expect(bodies[i]).notHasMaxHeightZero( - 'because collapsible bodies should be visible after being opened.' - ); //TODO replace with alternative for deprecated jasmine-jquery - M.Collapsible.getInstance(bodies[i].parentNode.parentNode).close(i); - } - expect(closeCallback).toEqual(true, 'because close callback fired'); - setTimeout(() => { - for (let i = 0; i < bodies.length; i++) { - expect(bodies[i]).hasMaxHeightZero( - 'because collapsible bodies should be hidden after close.' - ); //TODO replace with alternative for deprecated jasmine-jquery - } - done(); - }, 10); - }, 10); - }); - }); - - describe('accordion', () => { - it('should open first and second items, keeping only second open', (done) => { - // Collapsible body height should be 0 on start when hidden. - const firstHeader = accordion.querySelector('.collapsible-header'); - const firstBody = accordion.querySelector('.collapsible-body'); - const secondHeader = accordion.querySelectorAll('.collapsible-header')[1]; - const secondBody = accordion.querySelectorAll('.collapsible-body')[1]; - expect(firstBody).hasMaxHeightZero('because accordion bodies should be hidden initially.'); - expect(secondBody).hasMaxHeightZero('because accordion bodies should be hidden initially.'); - // Collapsible body height should be > 0 after being opened. - firstHeader.click(); - setTimeout(() => { - expect(firstBody).notHasMaxHeightZero( - 'because accordion bodies not visible after being opened.' - ); - click(secondHeader); - setTimeout(() => { - expect(firstBody).hasMaxHeightZero( - 'because accordion bodies should be hidden when another item is opened.' - ); - expect(secondBody).notHasMaxHeightZero( - 'because accordion bodies not visible after being opened.' - ); - done(); - }, 10); - }, 10); - }); - }); - - describe('popout', () => { - it('should open first and popout', (done) => { - // Collapsible body height should be 0 on start when hidden. - const listItems = popout.querySelectorAll('li'); - const firstHeader = popout.querySelector('.collapsible-header'); - const firstBody = popout.querySelector('.collapsible-body'); - expect(firstBody).hasMaxHeightZero('because accordion bodies should be hidden initially.'); - // Expect margin to be > 0 because not popped out. - for (let i = 0; i < listItems.length; i++) { - const listItemStyles = getComputedStyle(listItems[i]); - const marginLeft = parseInt(listItemStyles.getPropertyValue('margin-left')); - const marginRight = parseInt(listItemStyles.getPropertyValue('margin-right')); - expect(marginLeft).toBeGreaterThan( - 0, - 'because closed popout items should have horizontal margins.' - ); - expect(marginRight).toBeGreaterThan( - 0, - 'because closed popout items should have horizontal margins.' - ); - } - // expect margin to be 0 because popped out. - click(firstHeader); - setTimeout(() => { - const firstStyles = getComputedStyle(listItems[0]); - const firstMarginLeft = parseInt(firstStyles.getPropertyValue('margin-left')); - const firstMarginRight = parseInt(firstStyles.getPropertyValue('margin-right')); - expect(firstMarginLeft).toEqual( - 0, - 'because opened popout items should have no horizontal margins.' - ); - expect(firstMarginRight).toEqual( - 0, - 'because opened popout items should have no horizontal margins.' - ); - expect(firstBody).notHasMaxHeightZero( - 'because accordion bodies not visible after being opened.' - ); - done(); - }, 300); - }); - }); -}); diff --git a/components/collapsible/readme.md b/components/collapsible/readme.md new file mode 100644 index 0000000000..4deb8c8b24 --- /dev/null +++ b/components/collapsible/readme.md @@ -0,0 +1,5 @@ +# Collapsible + +or Accordion, ExpansibleTile, Expansion Panel + +not defined in the M3 Spec. diff --git a/components/navigation-drawer/sidenav.ts b/components/navigation-drawer/sidenav.ts index d1184b6dd4..7b5d053463 100644 --- a/components/navigation-drawer/sidenav.ts +++ b/components/navigation-drawer/sidenav.ts @@ -1,7 +1,7 @@ import { Utils } from '../../src/utils'; import { Component, BaseOptions, InitElements, MElement, Openable } from '../../src/component'; -export interface SidenavOptions extends BaseOptions { +interface SidenavOptions extends BaseOptions { /** * Side of screen on which Sidenav appears. * @default 'left' @@ -63,7 +63,7 @@ const _defaults: SidenavOptions = { preventScrolling: true }; -export class Sidenav extends Component implements Openable { +class Sidenav extends Component implements Openable { id: string; /** Describes open/close state of Sidenav. */ isOpen: boolean; @@ -544,3 +544,5 @@ export class Sidenav extends Component implements Openable { Sidenav._sidenavs = []; } } + +export { Sidenav, SidenavOptions }; diff --git a/components/tabs/tabs.ts b/components/tabs/tabs.ts index 47fa9afb02..50af294804 100644 --- a/components/tabs/tabs.ts +++ b/components/tabs/tabs.ts @@ -1,7 +1,7 @@ import { Carousel } from '../carousel/carousel'; import { Component, BaseOptions, InitElements, MElement } from '../../src/component'; -export interface TabsOptions extends BaseOptions { +interface TabsOptions extends BaseOptions { /** * Transition duration in milliseconds. * @default 300 @@ -33,7 +33,7 @@ const _defaults: TabsOptions = { responsiveThreshold: Infinity // breakpoint for swipeable }; -export class Tabs extends Component { +class Tabs extends Component { _tabLinks: NodeListOf; _index: number; _indicator: HTMLLIElement; @@ -356,3 +356,5 @@ export class Tabs extends Component { if (tab) (tab).click(); } } + +export { Tabs, TabsOptions }; diff --git a/examples/html/blog.html b/examples/html/blog.html index c38360f3a9..051d5f42e3 100644 --- a/examples/html/blog.html +++ b/examples/html/blog.html @@ -1,17 +1,17 @@ Materialize Web Blog - + + p, li { font-size: 1.2em; } +
-

Materialize Web Blog

Home > Articles > Crafting Sleek, Responsive Interfaces with MaterializeWeb
+

Materialize Web Blog

01/01/2026 posted by Daniel

Crafting Sleek, Responsive Interfaces with MaterializeWeb

In the fast-evolving landscape of web development, building clean, responsive, and intuitive user interfaces remains a top priority. While major CSS frameworks like Bootstrap have long dominated the scene, MaterializeWeb—the community-driven evolution of MaterializeCSS—offers a refreshing design philosophy anchored directly in Google’s Material Design principles.

diff --git a/examples/src/blog.js b/examples/src/blog.js index 44a2cfa74b..b3ebf85504 100644 --- a/examples/src/blog.js +++ b/examples/src/blog.js @@ -1,17 +1,11 @@ import { Text } from '../../components/atomic/atomic.mjs'; import { Component } from '../../components/atomic/component.mjs'; -import { Container, Page } from '../../components/atomic/page.mjs'; +import { Page, Container } from '../../components/atomic/page.mjs'; +import { Breadcrumb } from '../../components/breadcrumb/breadcrumb.mjs'; import { Button } from '../../components/button/button.mjs'; import { AssistChip } from '../../components/chip/chip.mjs'; -// class Link extends Component { -// constructor(options) { -// super(options); -// this.setTagName('a'); -// //this.setAttribute('href', options.href); -// } -// } - +// Article class BlogArticle extends Component { constructor(options) { super(options); @@ -19,7 +13,6 @@ class BlogArticle extends Component { this.addClassname('card').addClassname('p-5'); } } - const myArticle = new BlogArticle(`

01/01/2026 posted by Daniel

Crafting Sleek, Responsive Interfaces with MaterializeWeb

@@ -37,14 +30,17 @@ const myArticle = new BlogArticle(`

If you want your web applications to mirror the sleek, unified visual identity of modern mobile apps without spending weeks writing custom styles, MaterializeWeb is an outstanding choice. It strikes an ideal balance between aesthetic polish and developer efficiency, making it perfect for rapid prototyping and production-ready sites alike.

Give MaterializeWeb a try on your next project to experience how effortless modern visual design can be!

`); +// Page const blogPage = new Page({ title: 'Materialize Web Blog', description: 'This is a custom blog', keywords: 'News sites, personal journals, niche resource hubs, and content creators.', children: [ + // TODO: use Navigationbar Component new Container({ children: new Text('Materialize Web Blog').setTagName('p').addClassname('py-3') }), + new Container({ children: [ new AssistChip({ href: './landingpage.html', name: 'Visit Landingpage' }), @@ -52,12 +48,13 @@ const blogPage = new Page({ ] }) .addClassname('g-2') + .addClassname('p-2') + .addClassname('secondary') .addClassname('row'), - // TODO: use Breadcrumb Component - new Container({ - children: 'Home > Articles > Crafting Sleek, Responsive Interfaces with MaterializeWeb' - }).addClassname('py-5'), + new Breadcrumb() + .setCrumbs(['Home', 'Articles', 'Crafting Sleek, Responsive Interfaces with MaterializeWeb']) + .addClassname('py-5'), myArticle, new Container({ @@ -73,13 +70,19 @@ const blogPage = new Page({ children: 'Sidebar or navigation dropdowns ("Tech," "Lifestyle")' }).addClassname('py-5') ] -}).addStyleUrl('/dist/css/materialize.css') +}); + +// CSS +blogPage + .addStyleUrl('/dist/css/materialize.css') + .addStyleUrl('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined') .addStyle(`article { font-family: Times; line-height: 1.25; } h1 { font-size: 2.75em; } h2 { font-size: 2em; } h3 { font-size: 1.5em; } - p, li { font-size: 1.2em; } - `); + p, li { font-size: 1.2em; } + `); +// Render const html = blogPage.toHTML(); console.log(html); From 46da5d5194261eb826bc2fda11650a7b86ff70d0 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 08:57:04 +0200 Subject: [PATCH 13/60] test(cards): changed to vitest and fixed removing eventhandlers and initial state of reveal card --- components/appbar/appbar.test.mjs | 4 +- .../button/{fabSpec.js => ___fabSpec.js} | 0 .../button/___taptargetSpec.js | 0 .../card/{cardsSpec.js => cards.test.ts} | 121 +- components/card/cards.ts | 5 +- jasmine.json | 18 - package-lock.json | 1262 ++--------------- package.json | 3 - spec/helper.js | 338 ----- {spec => src}/scrollspySpec.js | 0 src/waves.js | 11 - 11 files changed, 171 insertions(+), 1591 deletions(-) rename components/button/{fabSpec.js => ___fabSpec.js} (100%) rename spec/taptargetSpec.js => components/button/___taptargetSpec.js (100%) rename components/card/{cardsSpec.js => cards.test.ts} (69%) delete mode 100644 jasmine.json delete mode 100644 spec/helper.js rename {spec => src}/scrollspySpec.js (100%) diff --git a/components/appbar/appbar.test.mjs b/components/appbar/appbar.test.mjs index 06fd8581b8..437ae055c0 100644 --- a/components/appbar/appbar.test.mjs +++ b/components/appbar/appbar.test.mjs @@ -1,8 +1,8 @@ -import { describe, expect, test } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { AppBar } from './appbar.mjs'; describe('appBar', () => { - test('create html', () => { + it('should create the html', () => { const appBar = new AppBar(); expect(appBar.toHTML()).toContain(' { const fixture = `
@@ -115,6 +126,7 @@ describe('Cards', () => {
`; + // Helper to safely fetch bounding dimensions in happy-dom const roundedRect = (el) => { const rect = el.getBoundingClientRect(); return { @@ -127,13 +139,41 @@ describe('Cards', () => { }; }; + // Helper function to simulate element click + const click = (el) => { + el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true })); + }; + + // Helper to check element visibility under happy-dom rules + const isVisible = (el) => { + const style = window.getComputedStyle(el); + return style.display !== 'none' && style.visibility !== 'hidden'; + }; + + // Helper to mock element layout measurements for Happy DOM + const mockRect = (el, rect) => { + vi.spyOn(el, 'getBoundingClientRect').mockReturnValue({ + top: rect.top || 0, + left: rect.left || 0, + width: rect.width || 0, + height: rect.height || 0, + right: (rect.left || 0) + (rect.width || 0), + bottom: (rect.top || 0) + (rect.height || 0), + x: rect.left || 0, + y: rect.top || 0, + toJSON: () => {} + }); + }; + beforeEach(() => { - XloadHtml(fixture); - M.Cards.init(document.querySelectorAll('.card')); + vi.useFakeTimers(); + document.body.innerHTML = fixture; + Cards.init(document.querySelectorAll('.card')); }); afterEach(() => { - XunloadFixtures(); + vi.useRealTimers(); + document.body.innerHTML = ''; }); describe('reveal cards', () => { @@ -146,40 +186,36 @@ describe('Cards', () => { }); it('should have a hidden card-reveal initially', () => { - expect(revealDiv).toBeHidden('reveal div should be hidden initially'); + expect(isVisible(revealDiv)).toBe(false); }); - it('should show card-reveal after clicking an activator', (done) => { + it('should show card-reveal after clicking an activator', () => { const activator = revealCard.querySelector('.activator'); click(activator); + vi.advanceTimersByTime(500); - setTimeout(() => { - expect(revealDiv).toBeVisible('reveal did not appear after activator was clicked.'); - done(); - }, 500); + expect(isVisible(revealDiv)).toBe(true); }); - it('should size and position card-reveal to cover the card when opened', (done) => { + it('should size and position card-reveal to cover the card when opened', () => { const activator = revealCard.querySelector('.activator'); + // Mock bounding box for happy-dom layout checks + mockRect(revealCard, { top: 10, left: 10, width: 300, height: 400 }); + mockRect(revealDiv, { top: 10, left: 10, width: 300, height: 400 }); + click(activator); + vi.advanceTimersByTime(500); - setTimeout(() => { - const revealRect = roundedRect(revealDiv); - const cardRect = roundedRect(revealCard); - - expect(revealDiv).toBeVisible('reveal did not appear after activator was clicked.'); - expect(revealRect.width).toEqual(cardRect.width, 'reveal width should match card width'); - expect(revealRect.height).toEqual( - cardRect.height, - 'reveal height should match card height' - ); - expect(revealRect.top).toEqual(cardRect.top, 'reveal top should align with card top'); - expect(revealRect.left).toEqual(cardRect.left, 'reveal left should align with card left'); - - done(); - }, 500); + const revealRect = roundedRect(revealDiv); + const cardRect = roundedRect(revealCard); + + expect(isVisible(revealDiv)).toBe(true); + expect(revealRect.width).toBe(cardRect.width); + expect(revealRect.height).toBe(cardRect.height); + expect(revealRect.top).toBe(cardRect.top); + expect(revealRect.left).toBe(cardRect.left); }); }); @@ -193,11 +229,14 @@ describe('Cards', () => { }); it('should have an image that fills the full width of the card', () => { + mockRect(imageCard, { top: 0, left: 0, width: 350, height: 450 }); + mockRect(image, { top: 0, left: 0, width: 350, height: 200 }); + const imageRect = roundedRect(image); const cardRect = roundedRect(imageCard); - expect(imageRect.width).toEqual(cardRect.width, 'image does not fill width of card'); - expect(imageRect.top).toEqual(cardRect.top, 'image top should align with card top'); + expect(imageRect.width).toBe(cardRect.width); + expect(imageRect.top).toBe(cardRect.top); }); }); @@ -213,26 +252,30 @@ describe('Cards', () => { const cardContent = card.querySelector('.card-content'); const cardAction = card.querySelector('.card-action'); + // Mock relative dimensions for Happy DOM layout calculation + mockRect(card, { top: 0, height: expectedHeight }); + mockRect(cardImage, { height: maxImageHeight - 10 }); + mockRect(cardContent, { height: maxContentHeight - 10 }); + mockRect(cardAction, { top: expectedHeight - 50, height: 50 }); + const cardRect = roundedRect(card); const imageRect = roundedRect(cardImage); const contentRect = roundedRect(cardContent); const actionRect = roundedRect(cardAction); - expect(cardRect.height).toEqual( - expectedHeight, - `${sizeName} card should be ${expectedHeight}px high` + expect(cardRect.height, `${sizeName} card should be ${expectedHeight}px high`).toBe( + expectedHeight ); - expect(imageRect.height).toBeLessThan( - maxImageHeight + 1, + expect( + imageRect.height, `${sizeName} image should be <= ${maxImageHeight}px high` - ); - expect(contentRect.height).toBeLessThan( - maxContentHeight + 1, + ).toBeLessThan(maxImageHeight + 1); + expect( + contentRect.height, `${sizeName} content should be <= ${maxContentHeight}px high` - ); - expect(actionRect.bottom).toEqual( - cardRect.bottom, - `${sizeName} action should be at bottom of card` + ).toBeLessThan(maxContentHeight + 1); + expect(actionRect.bottom, `${sizeName} action should be at bottom of card`).toBe( + cardRect.bottom ); }; diff --git a/components/card/cards.ts b/components/card/cards.ts index 3e2a707cbd..1b5ba34939 100644 --- a/components/card/cards.ts +++ b/components/card/cards.ts @@ -33,6 +33,7 @@ class Cards extends Component implements Openable { this.#cardReveal = this.el.querySelector('.card-reveal'); if (this.#cardReveal) { this.#initialOverflow = getComputedStyle(this.el).overflow; + this.#cardReveal.style.display = 'none'; this.#activators = Array.from(this.el.querySelectorAll('.activator')); this.#activators.forEach((el: HTMLElement) => { if (el) el.tabIndex = 0; @@ -119,8 +120,8 @@ class Cards extends Component implements Openable { }; #removeRevealCloseEventHandlers = () => { - this.#cardRevealClose.addEventListener('click', this.close); - this.#cardRevealClose.addEventListener('keypress', this.#handleKeypressCloseEvent); + this.#cardRevealClose.removeEventListener('click', this.close); + this.#cardRevealClose.removeEventListener('keypress', this.#handleKeypressCloseEvent); }; #handleKeypressCloseEvent: (e: KeyboardEvent) => void = (e: KeyboardEvent) => { diff --git a/jasmine.json b/jasmine.json deleted file mode 100644 index a75d4aca4b..0000000000 --- a/jasmine.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "srcDir": "dist", - "srcFiles": ["**/materialize.js"], - "specDir": ".", - "specFiles": ["components/**/*[sS]pec.js", "spec/*[sS]pec.js"], - "helpers": ["spec/helper.js"], - "cssFiles": ["**/materialize.css"], - "env": { - "stopSpecOnExpectationFailure": false, - "stopOnSpecFailure": false, - "random": true - }, - "listenAddress": "localhost", - "hostname": "localhost", - "browser": { - "name": "headlessChrome" - } -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5c48c3f4ee..af00712f5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,9 +35,6 @@ "eslint": "^9.10.0", "eslint-plugin-storybook": "^9.0.12", "happy-dom": "^20.11.1", - "jasmine": "^5.1.0", - "jasmine-browser-runner": "^2.5.0", - "jasmine-core": "^5.2.0", "postcss": "^8.4.49", "rollup": "^4.59.0", "rollup-plugin-copy": "^3.5.0", @@ -95,13 +92,6 @@ "node": ">=6.9.0" } }, - "node_modules/@bazel/runfiles": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@bazel/runfiles/-/runfiles-6.5.0.tgz", - "integrity": "sha512-RzahvqTkfpY2jsDxo8YItPX+/iZ6hbiikw1YhE0bA9EKBR5Og8Pa6FHn9PO9M0zaXRVsr0GFQLKbB/0rzy9SzA==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", @@ -1944,9 +1934,9 @@ "license": "MIT" }, "node_modules/@testing-library/user-event": { - "version": "14.6.3", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.3.tgz", - "integrity": "sha512-6dBq67jT8lE+JTE8Exm02Kt6ze43hz1jdiSpSJwtTZiT1xQQ6b7nZYTTQ9njdArdU8XklOwaDp/AbT/eYSKF4g==", + "version": "14.6.4", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.4.tgz", + "integrity": "sha512-QCGwP6QrjypBLwyj5cuyfVamkaIEy/XGY+1VDehbtbQqOggYmTFpFOdWR5mPz14vX8vXLMVjDHlRNBcClyO9ew==", "dev": true, "license": "MIT", "engines": { @@ -2071,17 +2061,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz", - "integrity": "sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.67.0.tgz", + "integrity": "sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/type-utils": "8.66.0", - "@typescript-eslint/utils": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", + "@typescript-eslint/scope-manager": "8.67.0", + "@typescript-eslint/type-utils": "8.67.0", + "@typescript-eslint/utils": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -2094,7 +2084,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.66.0", + "@typescript-eslint/parser": "^8.67.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -2110,16 +2100,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.66.0.tgz", - "integrity": "sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.67.0.tgz", + "integrity": "sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", + "@typescript-eslint/scope-manager": "8.67.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0", "debug": "^4.4.3" }, "engines": { @@ -2135,14 +2125,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.66.0.tgz", - "integrity": "sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.67.0.tgz", + "integrity": "sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.66.0", - "@typescript-eslint/types": "^8.66.0", + "@typescript-eslint/tsconfig-utils": "^8.67.0", + "@typescript-eslint/types": "^8.67.0", "debug": "^4.4.3" }, "engines": { @@ -2157,14 +2147,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz", - "integrity": "sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.67.0.tgz", + "integrity": "sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0" + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2175,9 +2165,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz", - "integrity": "sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.67.0.tgz", + "integrity": "sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==", "dev": true, "license": "MIT", "engines": { @@ -2192,15 +2182,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz", - "integrity": "sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.67.0.tgz", + "integrity": "sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/utils": "8.66.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0", + "@typescript-eslint/utils": "8.67.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -2217,9 +2207,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.66.0.tgz", - "integrity": "sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.67.0.tgz", + "integrity": "sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==", "dev": true, "license": "MIT", "engines": { @@ -2231,16 +2221,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz", - "integrity": "sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.67.0.tgz", + "integrity": "sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.66.0", - "@typescript-eslint/tsconfig-utils": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/visitor-keys": "8.66.0", + "@typescript-eslint/project-service": "8.67.0", + "@typescript-eslint/tsconfig-utils": "8.67.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/visitor-keys": "8.67.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2298,16 +2288,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.66.0.tgz", - "integrity": "sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.67.0.tgz", + "integrity": "sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.66.0", - "@typescript-eslint/types": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0" + "@typescript-eslint/scope-manager": "8.67.0", + "@typescript-eslint/types": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2322,13 +2312,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz", - "integrity": "sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.67.0.tgz", + "integrity": "sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/types": "8.67.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2566,20 +2556,6 @@ "node": ">=6.5" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", @@ -2701,13 +2677,6 @@ "dequal": "^2.0.3" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true, - "license": "MIT" - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -2883,9 +2852,9 @@ } }, "node_modules/bare-url": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.5.1.tgz", - "integrity": "sha512-cD5ciQuKlx+eumTCfqbfiL+fhQm+dHbVNB/cX4+d+I/nx4JsVop9VoFEPAs5RJ6I84QR6bZIBjpd2kjDOYeWcg==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.5.2.tgz", + "integrity": "sha512-L13PCJzKG8RGvx8V1/DdMi12ERhC3tprr7/8a94BxpmnRsFqxh5XZNdhtMxu5HPkRshYOOWRGY8lDP7ZhpG9Cg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2939,48 +2908,6 @@ "node": ">=12.0.0" } }, - "node_modules/body-parser": { - "version": "1.20.6", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", - "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.15.1", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, "node_modules/brace-expansion": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", @@ -3094,47 +3021,6 @@ "node": ">=4.0" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3284,29 +3170,6 @@ "dev": true, "license": "MIT" }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3314,23 +3177,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", - "dev": true, - "license": "MIT" - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -3440,16 +3286,6 @@ "node": ">=8" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -3460,17 +3296,6 @@ "node": ">=6" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -3503,21 +3328,6 @@ "license": "MIT", "peer": true }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -3525,33 +3335,10 @@ "dev": true, "license": "MIT" }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, - "license": "MIT" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/electron-to-chromium": { - "version": "1.5.403", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz", - "integrity": "sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==", + "version": "1.5.405", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.405.tgz", + "integrity": "sha512-bNglH7lPH5l+yHOes7Zr4VqxhOy4BQ9ZBUX4VdoFgxMpzJk7W1ZoO3Vgd9Pxa9PyjQ76sfm2aKH/nzEcCNRlew==", "dev": true, "license": "ISC" }, @@ -3562,16 +3349,6 @@ "dev": true, "license": "MIT" }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/entities": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", @@ -3585,16 +3362,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", @@ -3612,19 +3379,6 @@ "dev": true, "license": "MIT" }, - "node_modules/es-object-atoms": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", - "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/esbuild": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", @@ -3690,13 +3444,6 @@ "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, - "license": "MIT" - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3902,16 +3649,6 @@ "node": ">=0.10.0" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -3952,70 +3689,6 @@ "node": ">=12.0.0" } }, - "node_modules/express": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", - "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "~1.20.5", - "content-disposition": "~0.5.4", - "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.3.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "~0.1.12", - "proxy-addr": "~2.0.7", - "qs": "~6.15.1", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "~0.19.0", - "serve-static": "~1.16.2", - "setprototypeof": "1.2.0", - "statuses": "~2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4115,39 +3788,6 @@ "node": ">=16.0.0" } }, - "node_modules/filelist": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", - "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4161,42 +3801,6 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "statuses": "~2.0.2", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4252,16 +3856,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fraction.js": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", @@ -4276,16 +3870,6 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -4333,45 +3917,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -4488,19 +4033,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4537,23 +4069,10 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, "license": "MIT", "dependencies": { @@ -4563,40 +4082,6 @@ "node": ">= 0.4" } }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -4628,13 +4113,6 @@ "node": ">= 4" } }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true, - "license": "MIT" - }, "node_modules/immutable": { "version": "5.1.9", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz", @@ -4698,16 +4176,6 @@ "dev": true, "license": "ISC" }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-core-module": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", @@ -4849,64 +4317,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jake": { - "version": "10.9.4", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", - "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.6", - "filelist": "^1.0.4", - "picocolors": "^1.1.1" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jasmine": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-5.13.0.tgz", - "integrity": "sha512-oLCXIhEb5e0zzjn9GyuvcuisvLBwUjmgz7a0RNGWKwQtJCDld4m+vwKUpAIJVLB5vbmQFdtKhT86/tIZlJ5gYw==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^10.2.2", - "jasmine-core": "~5.13.0" - }, - "bin": { - "jasmine": "bin/jasmine.js" - } - }, - "node_modules/jasmine-browser-runner": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/jasmine-browser-runner/-/jasmine-browser-runner-2.5.0.tgz", - "integrity": "sha512-CzdvpeZunUu6x1u8G6/vPnfcKVpDaBFfk3tIvm1hoA+EfceQ8FRvsy4o8hEcKYyMt556XFRnP5PjYsxFU8z7Xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "ejs": "^3.1.6", - "express": "^4.19.2", - "glob": "^10.0.0", - "selenium-webdriver": "^4.12.0" - }, - "bin": { - "jasmine-browser-runner": "bin/jasmine-browser-runner" - }, - "peerDependencies": { - "jasmine-core": "^5.0.0" - } - }, - "node_modules/jasmine-core": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.13.0.tgz", - "integrity": "sha512-vsYjfh7lyqvZX5QgqKc4YH8phs7g96Z8bsdIFNEU3VqXhlHaq+vov/Fgn/sr6MiUczdZkyXRC3TX369Ll4Nzbw==", - "dev": true, - "license": "MIT" - }, "node_modules/js-tokens": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", @@ -4969,52 +4379,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dev": true, - "license": "(MIT OR GPL-3.0-or-later)", - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "node_modules/jszip/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/jszip/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jszip/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5085,16 +4449,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "immediate": "~3.0.5" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5160,36 +4514,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5200,16 +4524,6 @@ "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -5237,42 +4551,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -5339,16 +4617,6 @@ "dev": true, "license": "MIT" }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -5383,19 +4651,6 @@ "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", "license": "MIT" }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/obug": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", @@ -5410,19 +4665,6 @@ "node": ">=12.20.0" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5508,13 +4750,6 @@ "dev": true, "license": "BlueOak-1.0.0" }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true, - "license": "(MIT AND Zlib)" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5528,16 +4763,6 @@ "node": ">=6" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5592,13 +4817,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-to-regexp": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", - "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", - "dev": true, - "license": "MIT" - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -5739,20 +4957,6 @@ "dev": true, "license": "MIT" }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5763,23 +4967,6 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.15.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", - "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "es-define-property": "^1.0.1", - "side-channel": "^1.1.1" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5801,32 +4988,6 @@ ], "license": "MIT" }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react": { "version": "19.2.8", "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", @@ -5923,9 +5084,9 @@ } }, "node_modules/recast": { - "version": "0.23.20", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.20.tgz", - "integrity": "sha512-VtSf75pThDqsIUpdaYrTdQvkw10/+yP0i7+Cax7h+K9SRvYjrJURZcRlcHMrH6TMzV275Q8a2A8+G7y7W9zqsg==", + "version": "0.23.21", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.21.tgz", + "integrity": "sha512-mFAyJq9vUbSTARLZUvAEf1z3YxlvAwswbmxMx2mPA/MSm4KmpwvwvhsH/NIrZhyOuwD60Lzyw2qh83uCbgTPYw==", "dev": true, "license": "MIT", "dependencies": { @@ -5936,7 +5097,7 @@ "tslib": "^2.0.1" }, "engines": { - "node": ">= 22" + "node": ">= 4" } }, "node_modules/redent": { @@ -6163,13 +5324,6 @@ ], "license": "MIT" }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, "node_modules/sass": { "version": "1.102.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz", @@ -6198,32 +5352,6 @@ "dev": true, "license": "MIT" }, - "node_modules/selenium-webdriver": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.46.0.tgz", - "integrity": "sha512-UlTkgnx9y+bf3QxFsrgUyMqC2oy1Yf+qcOs7xIC/XfsUPv/ow7Sicx6SJ7AeOn2/Z+xF1M8SLqyn983wipI82w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/SeleniumHQ" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/selenium" - } - ], - "license": "Apache-2.0", - "dependencies": { - "@bazel/runfiles": "^6.5.0", - "jszip": "^3.10.1", - "tmp": "^0.2.7", - "ws": "^8.21.0" - }, - "engines": { - "node": ">= 20.0.0" - } - }, "node_modules/semver": { "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", @@ -6237,48 +5365,6 @@ "node": ">=10" } }, - "node_modules/send": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.4.1", - "range-parser": "~1.2.1", - "statuses": "~2.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.0.tgz", @@ -6289,36 +5375,6 @@ "node": ">=20.0.0" } }, - "node_modules/serve-static": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "~0.19.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true, - "license": "MIT" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, - "license": "ISC" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6342,82 +5398,6 @@ "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", - "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4", - "side-channel-list": "^1.0.1", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", - "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -6496,16 +5476,6 @@ "dev": true, "license": "MIT" }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/std-env": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", @@ -6744,9 +5714,9 @@ } }, "node_modules/terser": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.2.tgz", - "integrity": "sha512-rGbJiKeQ4WDe3EXlDAIaQcwftVfv2Q8o1awFNfvXolJYKkb1AuZY1RTOmqx4LJXZENbWZA7eIsYGHuEzHsi1nQ==", + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.50.0.tgz", + "integrity": "sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6833,16 +5803,6 @@ "node": ">=14.0.0" } }, - "node_modules/tmp": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", - "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6856,16 +5816,6 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -6909,20 +5859,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -6938,16 +5874,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.66.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.66.0.tgz", - "integrity": "sha512-QlEbBPz/RuJ1XUHj29nm3t0F/O/cSlEnntozqPOYHnnTGAXFamnMBu5i9Vn6vhUPHGAjR+Vl+5J8vPN/BMUrJw==", + "version": "8.67.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.67.0.tgz", + "integrity": "sha512-S2udFs8tCKEKffuJ4TB1idGUZiXdCPGi3IPBGWXarbLQ5UPXORV8QEVzJ4gCRduURMb5EkpNCdjbk0eDIuI8Yg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.66.0", - "@typescript-eslint/parser": "8.66.0", - "@typescript-eslint/typescript-estree": "8.66.0", - "@typescript-eslint/utils": "8.66.0" + "@typescript-eslint/eslint-plugin": "8.67.0", + "@typescript-eslint/parser": "8.67.0", + "@typescript-eslint/typescript-estree": "8.67.0", + "@typescript-eslint/utils": "8.67.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6978,16 +5914,6 @@ "node": ">= 4.0.0" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/unplugin": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", @@ -7003,9 +5929,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz", - "integrity": "sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", "dev": true, "funding": [ { @@ -7050,26 +5976,6 @@ "dev": true, "license": "MIT" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/vite": { "version": "7.3.6", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", diff --git a/package.json b/package.json index 83b5e3d22e..36717d05ee 100644 --- a/package.json +++ b/package.json @@ -73,9 +73,6 @@ "eslint": "^9.10.0", "eslint-plugin-storybook": "^9.0.12", "happy-dom": "^20.11.1", - "jasmine": "^5.1.0", - "jasmine-browser-runner": "^2.5.0", - "jasmine-core": "^5.2.0", "postcss": "^8.4.49", "rollup": "^4.59.0", "rollup-plugin-copy": "^3.5.0", diff --git a/spec/helper.js b/spec/helper.js deleted file mode 100644 index 84d04a73b7..0000000000 --- a/spec/helper.js +++ /dev/null @@ -1,338 +0,0 @@ -const KEYMAP = { - '27': 'Escape', - '32': 'Space', - '13': 'Enter', - '37': 'Left', - '39': 'Right', - '38': 'Up', - '40': 'Down', - '8': 'Backspace', - '9': 'Tab', - '16': 'Shift', - '17': 'Control', - '18': 'Alt', - '19': 'Pause', - '20': 'Capslock', - '160': 'LeftShift', - '161': 'RightShift', - '162': 'LeftControl', - '163': 'RightControl', - '164': 'LeftAlt', - '165': 'RightAlt', - '91': 'Windows', - '92': 'RightWindows', - '33': 'PageUp', - '34': 'PageDown', - '35': 'End', - '36': 'Home', - '44': 'PrintScreen', - '45': 'Insert', - '46': 'Delete', - '145': 'ScrollLock', - '186': 'Semicolon', - '187': 'Equals', - '188': 'Comma', - '189': 'Underscore', - '190': 'Period', - '191': 'Slash', - '192': 'Tilde', - '219': 'OpenBracket', - '220': 'BackSlash', - '221': 'CloseBracket', - '222': 'Quote', - '65': 'A', - '66': 'B', - '67': 'C', - '68': 'D', - '69': 'E', - '70': 'F', - '71': 'G', - '72': 'H', - '73': 'I', - '74': 'J', - '75': 'K', - '76': 'L', - '77': 'M', - '78': 'N', - '79': 'O', - '80': 'P', - '81': 'Q', - '82': 'R', - '83': 'S', - '84': 'T', - '85': 'U', - '86': 'V', - '87': 'W', - '88': 'X', - '89': 'Y', - '90': 'Z', - '48': 'D0', - '49': 'D1', - '50': 'D2', - '51': 'D3', - '52': 'D4', - '53': 'D5', - '54': 'D6', - '55': 'D7', - '56': 'D8', - '57': 'D9', - '112': 'F1', - '113': 'F2', - '114': 'F3', - '115': 'F4', - '116': 'F5', - '117': 'F6', - '118': 'F7', - '119': 'F8', - '120': 'F9', - '121': 'F10', - '122': 'F11', - '123': 'F12', - '124': 'F13', - '125': 'F14', - '126': 'F15', - '127': 'F16', - '128': 'F17', - '129': 'F18', - '130': 'F19', - '131': 'F20', - '132': 'F21', - '133': 'F22', - '134': 'F23', - '135': 'F24', - '144': 'Numlock', - '111': 'Divide', - '106': 'Multiply', - '107': 'Add', - '109': 'Subtract', - '110': 'NumpadDelete', - '96': '0', - '97': '1', - '98': '2', - '99': '3', - '100': '4', - '101': '5', - '102': '6', - '103': '7', - '104': '8', - '105': '9' -}; - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -function XloadHtml(html, options) { - options = options ? options : {}; - const defaultOptions = { insertionType: 'append' }; - options = { - ...defaultOptions, - ...options - }; - const div = document.createElement('div'); - div.classList.add('please-delete-me'); - div.innerHTML = html; - if (options.insertionType === 'append') { - document.body.appendChild(div); - } else if (options.insertionType === 'prepend') { - document.body.prepend(div); - } -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -function XunloadFixtures() { - document.querySelectorAll('.please-delete-me').forEach((el) => el.remove()); - document.querySelectorAll('.material-tooltip').forEach((el) => el.remove()); - document.querySelectorAll('.dropdown-content').forEach((el) => el.remove()); -} - -beforeEach(() => { - const matchers = { - toExist: (util, customEqualityTesters) => { - return { - compare: (actual) => { - const result = {}; - result.pass = util.equals(!!actual, true, customEqualityTesters); - return result; - } - }; - }, - hasMaxHeightZero: (util, customEqualityTesters) => { - return { - compare: (actual) => { - const style = getComputedStyle(actual); - const result = {}; - result.pass = util.equals( - style.getPropertyValue('max-height'), - '0px', - customEqualityTesters - ); - return result; - } - }; - }, - notHasMaxHeightZero: (util, customEqualityTesters) => { - return { - compare: (actual) => { - const style = getComputedStyle(actual); - const result = {}; - result.pass = !util.equals( - style.getPropertyValue('max-height'), - '0px', - customEqualityTesters - ); - return result; - } - }; - }, - toBeHidden: (util, customEqualityTesters) => { - return { - compare: (actual) => { - const style = getComputedStyle(actual); - const result = {}; - result.pass = util.equals( - style.getPropertyValue('display'), - 'none', - customEqualityTesters - ); - return result; - } - }; - }, - toBeVisible: (util, customEqualityTesters) => { - return { - compare: (actual) => { - const style = getComputedStyle(actual); - const result = {}; - result.pass = !util.equals( - style.getPropertyValue('display'), - 'none', - customEqualityTesters - ); - if (result.pass) { - result.pass = util.equals( - style.getPropertyValue('visibility'), - 'visible', - customEqualityTesters - ); - } - return result; - } - }; - }, - toHaveClass: (util, customEqualityTesters) => { - return { - compare: (actual, expected) => { - const result = {}; - result.pass = util.equals( - actual.classList.contains(expected), - true, - customEqualityTesters - ); - return result; - } - }; - }, - toNotHaveClass: (util, customEqualityTesters) => { - return { - compare: function (actual, expected) { - const result = {}; - result.pass = util.equals( - actual.classList.contains(expected), - false, - customEqualityTesters - ); - return result; - } - }; - } - }; - - jasmine.addMatchers(matchers); - - /** - * Creates standard click event on DOM element - */ - window.click = (elem) => { - const evt = document.createEvent('MouseEvent'); - evt.initMouseEvent('click', { - bubbles: true, - cancelable: true, - view: window - }); - elem.dispatchEvent(evt); - }; - - window.mouseenter = (el) => { - const ev = document.createEvent('MouseEvent'); - ev.initMouseEvent( - 'mouseenter', - true /* bubble */, - true /* cancelable */, - window, - null, - 0, - 0, - 0, - 0 /* coordinates */, - false, - false, - false, - false /* modifier keys */, - 0 /*left*/, - null - ); - el.dispatchEvent(ev); - }; - - window.mouseleave = (el) => { - const ev = document.createEvent('MouseEvent'); - ev.initMouseEvent( - 'mouseleave', - true /* bubble */, - true /* cancelable */, - window, - null, - 0, - 0, - 0, - 0 /* coordinates */, - false, - false, - false, - false /* modifier keys */, - 0 /*left*/, - null - ); - el.dispatchEvent(ev); - }; - - window.keydown = (targetElement, keycode) => { - targetElement.dispatchEvent( - new KeyboardEvent('keydown', { - key: KEYMAP[keycode], - keyCode: keycode, - which: keycode - }) - ); - }; - - window.keyup = (targetElement, keycode) => { - targetElement.dispatchEvent( - new KeyboardEvent('keyup', { - key: KEYMAP[keycode], - keyCode: keycode, - which: keycode - }) - ); - }; - - window.focus = (el) => { - const ev = document.createEvent('Events'); - ev.initEvent('focus', true, true); - el.dispatchEvent(ev); - }; - - window.blur = (el) => { - const ev = document.createEvent('Events'); - ev.initEvent('blur', true, true); - el.dispatchEvent(ev); - }; -}); diff --git a/spec/scrollspySpec.js b/src/scrollspySpec.js similarity index 100% rename from spec/scrollspySpec.js rename to src/scrollspySpec.js diff --git a/src/waves.js b/src/waves.js index 59076986d9..d7736120f2 100644 --- a/src/waves.js +++ b/src/waves.js @@ -1,14 +1,3 @@ -// type RGBColor = { -// r: number; -// g: number; -// b: number; -// }; - -// type Position = { -// x: number; -// y: number; -// }; - class Waves { /** * From db045b119da448353a6f5663b9e9f4f0b0595b93 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 10:00:32 +0200 Subject: [PATCH 14/60] test(tooltip): update to vitest --- .../{carouselSpec.js => ___carouselSpec.js} | 0 .../{sliderSpec.js => ___sliderSpec.js} | 0 components/chip/chip.test.ts | 12 +- ...datepickerSpec.js => ___datepickerSpec.js} | 0 ...terialboxSpec.js => ___materialboxSpec.js} | 0 .../dialog/{modalSpec.js => ___modalSpec.js} | 0 components/dialog/readme.md | 4 +- .../{dropdownSpec.js => ___dropdownSpec.js} | 0 .../{sidenavSpec.js => ___sidenavSpec.js} | 0 ...completeSpec.js => ___autocompleteSpec.js} | 0 .../{toastSpec.js => ___toastSpec.js} | 0 .../tabs/{tabsSpec.js => ___tabsSpec.js} | 0 .../{formsSpec.js => ___formsSpec.js} | 0 .../{selectSpec.js => ___selectSpec.js} | 0 components/tooltip/tooltip.css | 56 +++ components/tooltip/tooltip.test.ts | 129 +++++++ components/tooltip/tooltip.ts | 354 ++++-------------- components/tooltip/tooltipSpec.js | 145 ------- 18 files changed, 265 insertions(+), 435 deletions(-) rename components/carousel/{carouselSpec.js => ___carouselSpec.js} (100%) rename components/carousel/{sliderSpec.js => ___sliderSpec.js} (100%) rename components/datepicker/{datepickerSpec.js => ___datepickerSpec.js} (100%) rename components/dialog/{materialboxSpec.js => ___materialboxSpec.js} (100%) rename components/dialog/{modalSpec.js => ___modalSpec.js} (100%) rename components/dropdown/{dropdownSpec.js => ___dropdownSpec.js} (100%) rename components/navigation-drawer/{sidenavSpec.js => ___sidenavSpec.js} (100%) rename components/search/{autocompleteSpec.js => ___autocompleteSpec.js} (100%) rename components/snackbar/{toastSpec.js => ___toastSpec.js} (100%) rename components/tabs/{tabsSpec.js => ___tabsSpec.js} (100%) rename components/textfield/{formsSpec.js => ___formsSpec.js} (100%) rename components/textfield/{selectSpec.js => ___selectSpec.js} (100%) create mode 100644 components/tooltip/tooltip.css create mode 100644 components/tooltip/tooltip.test.ts delete mode 100644 components/tooltip/tooltipSpec.js diff --git a/components/carousel/carouselSpec.js b/components/carousel/___carouselSpec.js similarity index 100% rename from components/carousel/carouselSpec.js rename to components/carousel/___carouselSpec.js diff --git a/components/carousel/sliderSpec.js b/components/carousel/___sliderSpec.js similarity index 100% rename from components/carousel/sliderSpec.js rename to components/carousel/___sliderSpec.js diff --git a/components/chip/chip.test.ts b/components/chip/chip.test.ts index 862a2c9cdd..d2a1755f17 100644 --- a/components/chip/chip.test.ts +++ b/components/chip/chip.test.ts @@ -155,24 +155,24 @@ describe('Chips', () => { it('should have working callbacks', async () => { chips = document.querySelector('.chips.input-field'); let chipWasAdded = false; - let chipAddedElem: any = null; + let chipAddedElem = null; let chipSelect = false; - let chipSelected: any = null; + let chipSelected = null; let chipDelete = false; - let chipDeleted: any = null; + let chipDeleted = null; (global.M as any).Chips.init(chips, { allowUserInput: true, data: [{ id: 'One' }, { id: 'Two' }, { id: 'Three' }], - onChipAdd: (_chipsEl: any, chipEl: any) => { + onChipAdd: (_chipsEl, chipEl) => { chipAddedElem = chipEl; chipWasAdded = true; }, - onChipSelect: (_chipsEl: any, chipEl: any) => { + onChipSelect: (_chipsEl, chipEl) => { chipSelected = chipEl; chipSelect = true; }, - onChipDelete: (_chipsEl: any, chipEl: any) => { + onChipDelete: (_chipsEl, chipEl) => { chipDeleted = chipEl; chipDelete = true; } diff --git a/components/datepicker/datepickerSpec.js b/components/datepicker/___datepickerSpec.js similarity index 100% rename from components/datepicker/datepickerSpec.js rename to components/datepicker/___datepickerSpec.js diff --git a/components/dialog/materialboxSpec.js b/components/dialog/___materialboxSpec.js similarity index 100% rename from components/dialog/materialboxSpec.js rename to components/dialog/___materialboxSpec.js diff --git a/components/dialog/modalSpec.js b/components/dialog/___modalSpec.js similarity index 100% rename from components/dialog/modalSpec.js rename to components/dialog/___modalSpec.js diff --git a/components/dialog/readme.md b/components/dialog/readme.md index 0f8badda10..afbc1ab6db 100644 --- a/components/dialog/readme.md +++ b/components/dialog/readme.md @@ -1,5 +1,5 @@ # Dialog -*THIS SECTION IS FOR DEMONSTRATION ONLY* +TODO: Use the native html popover attribute and CSS only for this component. -Also called Modal. \ No newline at end of file +- [ ] Make a builder component diff --git a/components/dropdown/dropdownSpec.js b/components/dropdown/___dropdownSpec.js similarity index 100% rename from components/dropdown/dropdownSpec.js rename to components/dropdown/___dropdownSpec.js diff --git a/components/navigation-drawer/sidenavSpec.js b/components/navigation-drawer/___sidenavSpec.js similarity index 100% rename from components/navigation-drawer/sidenavSpec.js rename to components/navigation-drawer/___sidenavSpec.js diff --git a/components/search/autocompleteSpec.js b/components/search/___autocompleteSpec.js similarity index 100% rename from components/search/autocompleteSpec.js rename to components/search/___autocompleteSpec.js diff --git a/components/snackbar/toastSpec.js b/components/snackbar/___toastSpec.js similarity index 100% rename from components/snackbar/toastSpec.js rename to components/snackbar/___toastSpec.js diff --git a/components/tabs/tabsSpec.js b/components/tabs/___tabsSpec.js similarity index 100% rename from components/tabs/tabsSpec.js rename to components/tabs/___tabsSpec.js diff --git a/components/textfield/formsSpec.js b/components/textfield/___formsSpec.js similarity index 100% rename from components/textfield/formsSpec.js rename to components/textfield/___formsSpec.js diff --git a/components/textfield/selectSpec.js b/components/textfield/___selectSpec.js similarity index 100% rename from components/textfield/selectSpec.js rename to components/textfield/___selectSpec.js diff --git a/components/tooltip/tooltip.css b/components/tooltip/tooltip.css new file mode 100644 index 0000000000..9bb29ca7bd --- /dev/null +++ b/components/tooltip/tooltip.css @@ -0,0 +1,56 @@ +/* Reset popover default browser styles */ +.material-tooltip[popover] { + margin: 0; + border: none; + padding: 6px 10px; + background: #323232; + color: #fff; + border-radius: 4px; + font-size: 12px; + + /* Modern CSS Anchor Positioning */ + position: fixed; + position-fallback: --tooltip-fallback; + + /* Transition/Animation Handling */ + opacity: 0; + transition: + opacity 0.2s ease-out, + display 0.2s allow-discrete; +} + +/* Style for open state */ +.material-tooltip[popover]:popover-open { + opacity: 1; +} + +@starting-style { + .material-tooltip[popover]:popover-open { + opacity: 0; + } +} + +/* Position mapping using anchor positioning */ +.material-tooltip[data-position='top'] { + bottom: anchor(top); + justify-self: anchor-center; + margin-bottom: 5px; +} + +.material-tooltip[data-position='bottom'] { + top: anchor(bottom); + justify-self: anchor-center; + margin-top: 5px; +} + +.material-tooltip[data-position='left'] { + right: anchor(left); + align-self: anchor-center; + margin-right: 5px; +} + +.material-tooltip[data-position='right'] { + left: anchor(right); + align-self: anchor-center; + margin-left: 5px; +} diff --git a/components/tooltip/tooltip.test.ts b/components/tooltip/tooltip.test.ts new file mode 100644 index 0000000000..75ddd54dcf --- /dev/null +++ b/components/tooltip/tooltip.test.ts @@ -0,0 +1,129 @@ +// @vitest-environment happy-dom +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { Tooltip } from './tooltip'; + +const fixture = ` + + Hover me! + + + + Hover me! + + + +`; + +describe('Tooltip (Popover API)', () => { + beforeEach(() => { + // Setup fake timers for delay assertions + vi.useFakeTimers(); + + // Polyfill popover methods if Happy-DOM environment does not support native Popover API yet + if (!HTMLElement.prototype.showPopover) { + HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) { + this.setAttribute('popover-open', ''); + this.matches = (selector: string) => + selector === ':popover-open' || selector === '[popover]'; + }); + HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) { + this.removeAttribute('popover-open'); + this.matches = (selector: string) => selector === '[popover]'; + }); + } + + // Set up document fixture + document.body.innerHTML = fixture; + + // Initialize tooltips + Tooltip.init(document.querySelectorAll('.tooltipped'), { + enterDelay: 0, + exitDelay: 0 + }); + }); + + afterEach(() => { + document.body.innerHTML = ''; + vi.restoreAllMocks(); + vi.useRealTimers(); + }); + + describe('opens and closes properly', () => { + it('shows tooltip on mouse enter and hides on mouse leave', () => { + const tooltippedBtn = document.querySelector('#test')!; + const instance = Tooltip.getInstance(tooltippedBtn); + const tooltip = instance.tooltipEl; + + // Simulate mouse enter + tooltippedBtn.dispatchEvent(new Event('mouseenter')); + vi.advanceTimersByTime(10); + + // Verify content and open state + expect(instance.isOpen).toBe(true); + expect(tooltip.textContent).toBe('I am tooltip'); + + // Simulate mouse leave + tooltippedBtn.dispatchEvent(new Event('mouseleave')); + vi.advanceTimersByTime(10); + + expect(instance.isOpen).toBe(false); + }); + + it('removes tooltip DOM object on destroy', () => { + const tooltippedBtn = document.querySelector('#test1')!; + const instance = Tooltip.getInstance(tooltippedBtn); + const tooltipEl = instance.tooltipEl; + + instance.destroy(); + + // Check DOM cleanup & instance ref clearance + expect(Tooltip.getInstance(tooltippedBtn)).toBeUndefined(); + expect(document.body.contains(tooltipEl)).toBe(false); + }); + + it('changes position attribute dynamically', () => { + const tooltippedBtn = document.querySelector('#test')!; + tooltippedBtn.setAttribute('data-position', 'right'); + + const instance = Tooltip.getInstance(tooltippedBtn); + + tooltippedBtn.dispatchEvent(new Event('mouseenter')); + vi.advanceTimersByTime(10); + + expect(instance.tooltipEl.dataset.position).toBe('right'); + }); + + it('accepts delay option from javascript initialization', () => { + const tooltippedBtn = document.querySelector('#test')!; + tooltippedBtn.removeAttribute('data-delay'); + + // Re-initialize with a custom enterDelay + const instance = Tooltip.init(tooltippedBtn, { enterDelay: 200 }); + + tooltippedBtn.dispatchEvent(new Event('mouseenter')); + + // Check before delay completes + vi.advanceTimersByTime(150); + expect(instance.isOpen).toBe(false); + + // Check after delay passes + vi.advanceTimersByTime(100); + expect(instance.isOpen).toBe(true); + }); + + it('assigns correctly with a fixed position parent', () => { + const tooltippedBtn = document.querySelector('#test2')!; + const instance = Tooltip.getInstance(tooltippedBtn); + + tooltippedBtn.dispatchEvent(new Event('mouseenter')); + vi.advanceTimersByTime(10); + + expect(instance.isOpen).toBe(true); + expect(instance.tooltipEl.dataset.position).toBe('bottom'); + }); + }); +}); diff --git a/components/tooltip/tooltip.ts b/components/tooltip/tooltip.ts index dab16f88c8..7a05e74dec 100644 --- a/components/tooltip/tooltip.ts +++ b/components/tooltip/tooltip.ts @@ -1,101 +1,35 @@ -import { Utils } from '../../src/utils'; import { Component, BaseOptions, InitElements, MElement } from '../../src/component'; -// TODO: Rewrite this using popover and js only - -class Bounding { - left: number; // left offset coordinate - top: number; - width: number; - height: number; -} - export type TooltipPosition = 'top' | 'right' | 'bottom' | 'left'; export interface TooltipOptions extends BaseOptions { - /** - * Delay time before tooltip disappears. - * @default 200 - */ + /** Delay before tooltip disappears (ms) */ exitDelay: number; - /** - * Delay time before tooltip appears. - * @default 0 - */ + /** Delay before tooltip appears (ms) */ enterDelay: number; - /** - * Element Id for the tooltip. - * @default "" - */ + /** Custom element ID for existing content */ tooltipId?: string; - /** - * Text string for the tooltip. - * @default "" - */ + /** Text content for the tooltip */ text: string; - /** - * Set distance tooltip appears away from its activator - * excluding transitionMovement. - * @default 5 - */ - margin: number; - /** - * Enter transition duration. - * @default 300 - */ - inDuration: number; - /** - * Opacity of the tooltip. - * @default 1 - */ - opacity: number; - /** - * Exit transition duration. - * @default 250 - */ - outDuration: number; - /** - * Set the direction of the tooltip. - * @default 'bottom' - */ + /** Position relative to the anchor */ position: TooltipPosition; - /** - * Amount in px that the tooltip moves during its transition. - * @default 10 - */ - transitionMovement: number; } const _defaults: TooltipOptions = { exitDelay: 200, enterDelay: 0, text: '', - margin: 5, - inDuration: 250, - outDuration: 200, - position: 'bottom' as TooltipPosition, - transitionMovement: 10, - opacity: 1 + position: 'bottom' }; export class Tooltip extends Component { - /** - * If tooltip is open. - */ - isOpen: boolean; - /** - * If tooltip is hovered. - */ - isHovered: boolean; - /** - * If tooltip is focused. - */ - isFocused: boolean; + isOpen: boolean = false; + isHovered: boolean = false; + isFocused: boolean = false; + tooltipEl: HTMLElement; - private _exitDelayTimeout: string | number | NodeJS.Timeout; - private _enterDelayTimeout: string | number | NodeJS.Timeout; - xMovement: number; - yMovement: number; + private _enterTimeout: number | NodeJS.Timeout; + private _exitTimeout: number | NodeJS.Timeout; constructor(el: HTMLElement, options: Partial) { super(el, options, Tooltip); @@ -107,10 +41,7 @@ export class Tooltip extends Component { ...options }; - this.isOpen = false; - this.isHovered = false; - this.isFocused = false; - this._appendTooltipEl(); + this._setupPopoverElement(); this._setupEventHandlers(); } @@ -118,23 +49,8 @@ export class Tooltip extends Component { return _defaults; } - /** - * Initializes instance of Tooltip. - * @param el HTML element. - * @param options Component options. - */ static init(el: HTMLElement, options?: Partial): Tooltip; - /** - * Initializes instances of Tooltip. - * @param els HTML elements. - * @param options Component options. - */ static init(els: InitElements, options?: Partial): Tooltip[]; - /** - * Initializes instances of Tooltip. - * @param els HTML elements. - * @param options Component options. - */ static init( els: HTMLElement | InitElements, options: Partial = {} @@ -149,237 +65,111 @@ export class Tooltip extends Component { destroy() { this.tooltipEl.remove(); this._removeEventHandlers(); - this.el['M_Tooltip'] = undefined; + delete this.el['M_Tooltip']; } - _appendTooltipEl() { - this.tooltipEl = document.createElement('div'); - this.tooltipEl.classList.add('material-tooltip'); + private _setupPopoverElement() { + if (this.options.tooltipId) { + this.tooltipEl = document.getElementById(this.options.tooltipId); + } else { + this.tooltipEl = document.createElement('div'); + this.tooltipEl.className = 'material-tooltip'; + this.tooltipEl.textContent = this.options.text; + document.body.appendChild(this.tooltipEl); + } - const tooltipContentEl = this.options.tooltipId - ? document.getElementById(this.options.tooltipId) - : document.createElement('div'); - this.tooltipEl.append(tooltipContentEl); - tooltipContentEl.style.display = ''; + // Set native popover attributes + this.tooltipEl.popover = 'manual'; - tooltipContentEl.classList.add('tooltip-content'); - this._setTooltipContent(tooltipContentEl); - this.tooltipEl.appendChild(tooltipContentEl); - document.body.appendChild(this.tooltipEl); - } - - _setTooltipContent(tooltipContentEl: HTMLElement) { - if (this.options.tooltipId) return; - tooltipContentEl.innerText = this.options.text; - } + // Assign unique anchor name linking the element and popover + const anchorName = `--tooltip-anchor-${Math.random().toString(36).substring(2, 9)}`; + (this.el.style as any).anchorName = anchorName; + (this.tooltipEl.style as any).positionAnchor = anchorName; - _updateTooltipContent() { - this._setTooltipContent(this.tooltipEl.querySelector('.tooltip-content')); + // Set default position class/data-attribute for CSS positioning + this.tooltipEl.dataset.position = this.options.position; } - _setupEventHandlers() { + private _setupEventHandlers() { this.el.addEventListener('mouseenter', this._handleMouseEnter); this.el.addEventListener('mouseleave', this._handleMouseLeave); - this.el.addEventListener('focus', this._handleFocus, true); - this.el.addEventListener('blur', this._handleBlur, true); + this.el.addEventListener('focus', this._handleFocus); + this.el.addEventListener('blur', this._handleBlur); } - _removeEventHandlers() { + private _removeEventHandlers() { this.el.removeEventListener('mouseenter', this._handleMouseEnter); this.el.removeEventListener('mouseleave', this._handleMouseLeave); - this.el.removeEventListener('focus', this._handleFocus, true); - this.el.removeEventListener('blur', this._handleBlur, true); + this.el.removeEventListener('focus', this._handleFocus); + this.el.removeEventListener('blur', this._handleBlur); } - /** - * Show tooltip. - */ - open = (isManual: boolean) => { + open = (isManual = true) => { if (this.isOpen) return; - isManual = isManual === undefined ? true : undefined; // Default value true - this.isOpen = true; - // Update tooltip content with HTML attribute options + + clearTimeout(this._exitTimeout); this.options = { ...this.options, ...this._getAttributeOptions() }; - this._updateTooltipContent(); - this._setEnterDelayTimeout(isManual); + this._updateContent(); + + this._enterTimeout = setTimeout(() => { + if (!isManual && !this.isHovered && !this.isFocused) return; + + this.tooltipEl.showPopover(); + this.isOpen = true; + }, this.options.enterDelay); }; - /** - * Hide tooltip. - */ close = () => { if (!this.isOpen) return; + + clearTimeout(this._enterTimeout); this.isHovered = false; this.isFocused = false; - this.isOpen = false; - this._setExitDelayTimeout(); - }; - _setExitDelayTimeout() { - clearTimeout(this._exitDelayTimeout); - this._exitDelayTimeout = setTimeout(() => { + this._exitTimeout = setTimeout(() => { if (this.isHovered || this.isFocused) return; - this._animateOut(); - }, this.options.exitDelay); - } - - _setEnterDelayTimeout(isManual) { - clearTimeout(this._enterDelayTimeout); - this._enterDelayTimeout = setTimeout(() => { - if (!this.isHovered && !this.isFocused && !isManual) return; - this._animateIn(); - }, this.options.enterDelay); - } - _positionTooltip() { - const tooltip: HTMLElement = this.tooltipEl; - const origin = this.el as HTMLElement, - originHeight = origin.offsetHeight, - originWidth = origin.offsetWidth, - tooltipHeight = tooltip.offsetHeight, - tooltipWidth = tooltip.offsetWidth, - margin = this.options.margin; - - this.xMovement = 0; - this.yMovement = 0; - - let targetTop = origin.getBoundingClientRect().top + Utils.getDocumentScrollTop(); - let targetLeft = origin.getBoundingClientRect().left + Utils.getDocumentScrollLeft(); - if (this.options.position === 'top') { - targetTop += -tooltipHeight - margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = -this.options.transitionMovement; - } else if (this.options.position === 'right') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += originWidth + margin; - this.xMovement = this.options.transitionMovement; - } else if (this.options.position === 'left') { - targetTop += originHeight / 2 - tooltipHeight / 2; - targetLeft += -tooltipWidth - margin; - this.xMovement = -this.options.transitionMovement; - } else { - targetTop += originHeight + margin; - targetLeft += originWidth / 2 - tooltipWidth / 2; - this.yMovement = this.options.transitionMovement; - } - - const newCoordinates = this._repositionWithinScreen( - targetLeft, - targetTop, - tooltipWidth, - tooltipHeight - ); - - tooltip.style.top = newCoordinates.y + 'px'; - tooltip.style.left = newCoordinates.x + 'px'; - } - - _repositionWithinScreen(x: number, y: number, width: number, height: number) { - const scrollLeft = Utils.getDocumentScrollLeft(); - const scrollTop = Utils.getDocumentScrollTop(); - let newX = x - scrollLeft; - let newY = y - scrollTop; - - const bounding: Bounding = { - left: newX, - top: newY, - width: width, - height: height - }; - const offset = this.options.margin + this.options.transitionMovement; - const edges = Utils.checkWithinContainer(document.body, bounding, offset); + this.tooltipEl.hidePopover(); + this.isOpen = false; + }, this.options.exitDelay); + }; - if (edges.left) { - newX = offset; - } else if (edges.right) { - newX -= newX + width - window.innerWidth; + private _updateContent() { + if (!this.options.tooltipId) { + this.tooltipEl.textContent = this.options.text; } - if (edges.top) { - newY = offset; - } else if (edges.bottom) { - newY -= newY + height - window.innerHeight; - } - return { - x: newX + scrollLeft, - y: newY + scrollTop - }; + this.tooltipEl.dataset.position = this.options.position; } - _animateIn() { - this._positionTooltip(); - this.tooltipEl.style.visibility = 'visible'; - const duration = this.options.inDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`; - this.tooltipEl.style.opacity = (this.options.opacity || 1).toString(); - }, 1); - } - - _animateOut() { - const duration = this.options.outDuration; - // easeOutCubic - this.tooltipEl.style.transition = ` - transform ${duration}ms ease-out, - opacity ${duration}ms ease-out`; - setTimeout(() => { - this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`; - this.tooltipEl.style.opacity = '0'; - }, 1); - /* - anim.remove(this.tooltipEl); - anim({ - targets: this.tooltipEl, - opacity: 0, - translateX: 0, - translateY: 0, - duration: this.options.outDuration, - easing: 'easeOutCubic' - }); - */ - } - - _handleMouseEnter = () => { + private _handleMouseEnter = () => { this.isHovered = true; - this.isFocused = false; // Allows close of tooltip when opened by focus. this.open(false); }; - _handleMouseLeave = () => { + private _handleMouseLeave = () => { this.isHovered = false; - this.isFocused = false; // Allows close of tooltip when opened by focus. this.close(); }; - _handleFocus = () => { - if (Utils.tabPressed) { - this.isFocused = true; - this.open(false); - } + private _handleFocus = () => { + this.isFocused = true; + this.open(false); }; - _handleBlur = () => { + private _handleBlur = () => { this.isFocused = false; this.close(); }; - _getAttributeOptions(): Partial { + private _getAttributeOptions(): Partial { const attributeOptions: Partial = {}; - const tooltipTextOption = this.el.getAttribute('data-tooltip'); + const text = this.el.getAttribute('data-tooltip'); + const position = this.el.getAttribute('data-position') as TooltipPosition; const tooltipId = this.el.getAttribute('data-tooltip-id'); - const positionOption = this.el.getAttribute('data-position'); - if (tooltipTextOption) { - attributeOptions.text = tooltipTextOption; - } - if (positionOption) { - attributeOptions.position = positionOption as TooltipPosition; - } - if (tooltipId) { - attributeOptions.tooltipId = tooltipId; - } + + if (text) attributeOptions.text = text; + if (position) attributeOptions.position = position; + if (tooltipId) attributeOptions.tooltipId = tooltipId; return attributeOptions; } diff --git a/components/tooltip/tooltipSpec.js b/components/tooltip/tooltipSpec.js deleted file mode 100644 index 5ed2697fde..0000000000 --- a/components/tooltip/tooltipSpec.js +++ /dev/null @@ -1,145 +0,0 @@ -describe('Tooltip:', () => { - const fixture = ` - Hover me! - - - - Hover me! - - -



















-



















-



















-



















- -`; - - beforeEach(() => { - XloadHtml(fixture); - M.Tooltip.init(document.querySelectorAll('.tooltipped'), { - enterDelay: 0, - exitDelay: 0, - inDuration: 0, - outDuration: 0 - }); - }); - afterEach(() => XunloadFixtures()); - - describe('opens and closes properly', () => { - it('shows tooltip on mouse enter', (done) => { - const tooltippedBtn = document.querySelector('#test'); - const tooltip = M.Tooltip.getInstance(tooltippedBtn).tooltipEl; - mouseenter(tooltippedBtn); - setTimeout(() => { - expect(tooltip).toBeVisible('because mouse entered tooltipped btn'); - expect(tooltip.querySelector('.tooltip-content').innerText).toBe( - 'I am tooltip', - 'because that is the defined text in the html attribute' - ); - mouseleave(tooltippedBtn); - setTimeout(() => { - expect(tooltip).toBeVisible('because mouse left tooltipped btn'); - done(); - }, 10); - }, 10); - }); - - it('should place tooltips on the bottom within the screen bounds', (done) => { - const tooltippedBtn = document.querySelector('#test1'); - const tooltip = M.Tooltip.getInstance(tooltippedBtn).tooltipEl; - mouseenter(tooltippedBtn); - // tooltippedBtn.trigger('mouseenter'); - setTimeout(() => { - const tooltipRect = tooltip.getBoundingClientRect(); - const tooltippedBtnRect = tooltippedBtn.getBoundingClientRect(); - // Check window bounds - expect(tooltipRect.top).toBeGreaterThanOrEqual(0); - expect(tooltipRect.bottom).toBeLessThanOrEqual(window.innerHeight); - expect(tooltipRect.left).toBeGreaterThanOrEqual(0); - expect(tooltipRect.right).toBeLessThanOrEqual(window.innerWidth); - // check if tooltip is under btn - expect(tooltipRect.top).toBeGreaterThan(tooltippedBtnRect.bottom); - done(); - }, 10); - }); - - it('removes tooltip dom object', () => { - const tooltippedBtn = document.querySelector('#test1'); - M.Tooltip.getInstance(tooltippedBtn).destroy(); - // Check DOM element is removed - const tooltipInstance = M.Tooltip.getInstance(tooltippedBtn); - expect(tooltipInstance).toBe(undefined); - }); - - it('changes position attribute dynamically and positions tooltips on the right correctly', (done) => { - const tooltippedBtn = document.querySelector('#test'); - tooltippedBtn.setAttribute('data-position', 'right'); - const tooltip = M.Tooltip.getInstance(tooltippedBtn).tooltipEl; - mouseenter(tooltippedBtn); - setTimeout(() => { - const tooltipRect = tooltip.getBoundingClientRect(); - const tooltippedBtnRect = tooltippedBtn.getBoundingClientRect(); - expect(tooltipRect.left).toBeGreaterThan(tooltippedBtnRect.right); - done(); - }, 10); - }); - - it('accepts delay option from javascript initialization', (done) => { - const tooltippedBtn = document.querySelector('#test'); - tooltippedBtn.removeAttribute('data-delay'); - M.Tooltip.init(tooltippedBtn, { enterDelay: 200 }); - const tooltip = M.Tooltip.getInstance(tooltippedBtn).tooltipEl; - mouseenter(tooltippedBtn); - setTimeout(() => { - const tooltipVisibility = getComputedStyle(tooltip).getPropertyValue('visibility'); - expect(tooltipVisibility).toBe('hidden', 'because the delay is 200 seconds'); - }, 150); - setTimeout(() => { - expect(tooltip).toBeVisible('because 200 seconds has passed'); - done(); - }, 250); - }); - - it('works with a fixed position parent', (done) => { - const tooltippedBtn = document.querySelector('#test2'); - const tooltip = M.Tooltip.getInstance(tooltippedBtn).tooltipEl; - mouseenter(tooltippedBtn); - setTimeout(() => { - const tooltipRect = tooltip.getBoundingClientRect(); - const tooltippedBtnRect = tooltippedBtn.getBoundingClientRect(); - const verticalDiff = tooltipRect.top - tooltippedBtnRect.top; - const horizontalDiff = - tooltipRect.left + - tooltipRect.width / 2 - - (tooltippedBtnRect.left + tooltippedBtnRect.width / 2); - // 52 is magic number for tooltip vertical offset... increased to 100 - expect(verticalDiff > 0 && verticalDiff < 100).toBeTruthy( - 'top position in fixed to be correct' - ); - expect(horizontalDiff > -1 && horizontalDiff < 1).toBeTruthy( - 'left position in fixed to be correct' - ); - done(); - }, 10); - }); - }); -}); From 7c24caf1a182a9fff5833262a744a497bc3f36f3 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 10:28:43 +0200 Subject: [PATCH 15/60] test(tabs): convert to vitest --- components/tabs/___tabsSpec.js | 180 ---------------- components/tabs/tabs.test.ts | 195 ++++++++++++++++++ components/tabs/tabs.ts | 161 +++++++-------- .../{_tooltip.scss => ___del_tooltip.scss} | 0 package.json | 5 +- sass/materialize.scss | 2 +- 6 files changed, 274 insertions(+), 269 deletions(-) delete mode 100644 components/tabs/___tabsSpec.js create mode 100644 components/tabs/tabs.test.ts rename components/tooltip/{_tooltip.scss => ___del_tooltip.scss} (100%) diff --git a/components/tabs/___tabsSpec.js b/components/tabs/___tabsSpec.js deleted file mode 100644 index 93427b6a80..0000000000 --- a/components/tabs/___tabsSpec.js +++ /dev/null @@ -1,180 +0,0 @@ -describe('Tabs Plugin', () => { - const fixture = `
- -
Test 1
-
Test 2
-
Test 3
-
Test 4
-
Test 1
-
Test 2
-
Test 3
-
Test 4
-
`; - - beforeEach(() => { - XloadHtml(fixture); - const normalTabs = document.querySelector('.tabs.normal'); - M.Tabs.init(normalTabs, { duration: 0 }); - window.location.hash = ''; - //HACK the tabs init function not fully initializing. it restores state even after element has been removed from DOM, even after using tabInstance.destroy() - M.Tabs.getInstance(normalTabs).select('test2'); - }); - afterEach(() => XunloadFixtures()); - - describe('Tabs', () => { - it('should open to active tab', () => { - const normalTabs = document.querySelector('.tabs.normal'); - const activeTab = normalTabs.querySelector('.active'); - const activeTabHash = activeTab.getAttribute('href'); - const tabLinks = normalTabs.querySelectorAll('.tab a'); - for (let i = 0; i < tabLinks.length; i++) { - const tabHash = tabLinks[i].getAttribute('href'); - if (tabHash === activeTabHash) { - expect(document.querySelector(tabHash)).toBeVisible( - 'active tab content should be visible by default' - ); //TODO replace with alternative for deprecated jasmine-jquery - } else { - expect(document.querySelector(tabHash)).toBeHidden( - 'Tab content should be hidden by default' - ); //TODO replace with alternative for deprecated jasmine-jquery - } - } - const indicator = normalTabs.querySelector('.indicator'); - expect(indicator).toExist('Indicator should be generated'); - // expect(Math.abs(indicator.offset().left - activeTab.offset().left)).toBeLessThan(1, 'Indicator should be at active tab by default.'); - }); - - it('should switch to clicked tab', (done) => { - const normalTabs = document.querySelector('.tabs.normal'); - const activeTab = normalTabs.querySelector('.active'); - const activeTabHash = activeTab.getAttribute('href'); - const disabledTab = normalTabs.querySelector('.disabled a'); - const disabledTabHash = disabledTab.getAttribute('href'); - const firstTab = normalTabs.querySelector('.tab a'); - const firstTabHash = firstTab.getAttribute('href'); - const indicator = normalTabs.querySelector('.indicator'); - expect(indicator).toExist('Indicator should be generated'); - // expect(Math.abs(indicator.offset().left - activeTab.offset().left)).toBeLessThan(1, 'Indicator should be at active tab by default.'); - click(disabledTab); - setTimeout(() => { - expect(document.querySelector(activeTabHash)).toBeVisible( - 'Clicking disabled should not change tabs.' - ); //TODO replace with alternative for deprecated jasmine-jquery - expect(document.querySelector(disabledTabHash)).toBeHidden( - 'Clicking disabled should not change tabs.' - ); //TODO replace with alternative for deprecated jasmine-jquery - - click(firstTab); - - setTimeout(() => { - expect(document.querySelector(activeTabHash)).toBeHidden( - 'Clicking tab should switch to that tab.' - ); //TODO replace with alternative for deprecated jasmine-jquery - expect(document.querySelector(firstTabHash)).toBeVisible( - 'Clicking tab should switch to that tab.' - ); //TODO replace with alternative for deprecated jasmine-jquery - expect(indicator.offsetLeft).toEqual( - firstTab.offsetLeft, - 'Indicator should move to clicked tab.' - ); - done(); - }, 10); // 400 - }, 10); // 400 - }); - - it("shouldn't hide active tab if clicked while active", (done) => { - const normalTabs = document.querySelector('.tabs.normal'); - const activeTab = normalTabs.querySelector('.active'); - const activeTabHash = activeTab.getAttribute('href'); - const indicator = normalTabs.querySelector('.indicator'); - expect(indicator).toExist('Indicator should be generated'); - click(activeTab); - setTimeout(() => { - expect(document.querySelector(activeTabHash)).toBeVisible( - 'Clicking active tab while active should not hide it.' - ); - done(); - }, 5); // 400 - }); - - it('should horizontally scroll when too many tabs', (done) => { - let tabsScrollWidth = 0; - const normalTabs = document.querySelector('.tabs.normal'); - normalTabs.style.width = '400px'; - const tabs = normalTabs.querySelectorAll('.tab'); - for (let i = 0; i < tabs.length; i++) { - setTimeout(() => { - tabsScrollWidth += tabs[i].offsetWidth; - }, 0); - } - - setTimeout(() => { - expect(tabsScrollWidth).toBeGreaterThan( - normalTabs.offsetWidth, - 'Scroll width should exceed tabs width' - ); - done(); - }, 5); // 400 - }); - - it('should programmatically switch tabs', (done) => { - const normalTabs = document.querySelector('.tabs.normal'); - const activeTab = normalTabs.querySelector('.active'); - const activeTabHash = activeTab.getAttribute('href'); - const firstTab = normalTabs.querySelector('li a'); - const firstTabHash = firstTab.getAttribute('href'); - const indicator = normalTabs.querySelector('.indicator'); - const tabs = normalTabs.querySelectorAll('.tab a'); - for (let i = 0; i < tabs.length; i++) { - const tabHash = tabs[i].getAttribute('href'); - if (tabHash === activeTabHash) { - expect(document.querySelector(tabHash)).toBeVisible( - 'active tab content should be visible by default' - ); //TODO replace with alternative for deprecated jasmine-jquery - } else { - expect(document.querySelector(tabHash)).toBeHidden( - 'Tab content should be hidden by default' - ); //TODO replace with alternative for deprecated jasmine-jquery - } - } - - M.Tabs.getInstance(normalTabs).select('test1'); - - setTimeout(() => { - expect(document.querySelector(activeTabHash)).toBeHidden( - 'Clicking tab should switch to that tab.' - ); //TODO replace with alternative for deprecated jasmine-jquery - expect(document.querySelector(firstTabHash)).toBeVisible( - 'Clicking tab should switch to that tab.' - ); //TODO replace with alternative for deprecated jasmine-jquery - expect(indicator.offsetLeft).toEqual( - firstTab.offsetLeft, - 'Indicator should move to clicked tab.' - ); - done(); - }, 5); // 400 - }); - - it("shouldn't error if tab has no associated content", (done) => { - document.querySelector('#test8').remove(); - const tabNoContent = document.querySelector('[href="#test8"]'); - expect(tabNoContent).toNotHaveClass('active', 'Tab should not be selected'); - click(tabNoContent); - setTimeout(() => { - expect(tabNoContent).toHaveClass('active', 'Tab should be selected even with no content'); - done(); - }, 10); // 400 - }); - }); -}); diff --git a/components/tabs/tabs.test.ts b/components/tabs/tabs.test.ts new file mode 100644 index 0000000000..c19ce35a16 --- /dev/null +++ b/components/tabs/tabs.test.ts @@ -0,0 +1,195 @@ +// @vitest-environment happy-dom +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; +import { Tabs } from './tabs.ts'; + +// Helper utility for async delays +const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + +describe('Tabs Plugin', () => { + const fixture = `
+ +
Test 1
+
Test 2
+
Test 3
+
Test 4
+
Test 5
+
Test 6
+
Test 7
+
Test 8
+
`; + + let container: HTMLDivElement; + + beforeEach(() => { + // Mount fixture + container = document.createElement('div'); + container.innerHTML = fixture; + document.body.appendChild(container); + + const normalTabs = document.querySelector('.tabs.normal')!; + Tabs.init(normalTabs, { duration: 0 }); + window.location.hash = ''; + + // Force selection of test2 as active tab + Tabs.getInstance(normalTabs)?.select('test2'); + }); + + afterEach(() => { + const normalTabs = document.querySelector('.tabs.normal'); + if (normalTabs) { + Tabs.getInstance(normalTabs)?.destroy(); + } + document.body.innerHTML = ''; + }); + + describe('Tabs', () => { + it('should open to active tab', () => { + const normalTabs = document.querySelector('.tabs.normal')!; + const activeTab = normalTabs.querySelector('.active')!; + const activeTabHash = activeTab.getAttribute('href')!; + const tabLinks = normalTabs.querySelectorAll('.tab a'); + + tabLinks.forEach((tabLink) => { + const tabHash = tabLink.getAttribute('href')!; + const contentEl = document.querySelector(tabHash)!; + + if (tabHash === activeTabHash) { + expect(contentEl.style.display).not.toBe('none'); + } else { + expect(contentEl.style.display).toBe('none'); + } + }); + + const indicator = normalTabs.querySelector('.indicator'); + expect(indicator).not.toBeNull(); + }); + + it('should switch to clicked tab', async () => { + const normalTabs = document.querySelector('.tabs.normal')!; + const activeTab = normalTabs.querySelector('.active')!; + const activeTabHash = activeTab.getAttribute('href')!; + const disabledTab = normalTabs.querySelector('.disabled a')!; + const disabledTabHash = disabledTab.getAttribute('href')!; + const firstTab = normalTabs.querySelector('.tab a')!; + const firstTabHash = firstTab.getAttribute('href')!; + const indicator = normalTabs.querySelector('.indicator')!; + + expect(indicator).not.toBeNull(); + + // Click disabled tab + disabledTab.click(); + await delay(10); + + const activeContent = document.querySelector(activeTabHash)!; + const disabledContent = document.querySelector(disabledTabHash)!; + + expect(activeContent.style.display).not.toBe('none'); + expect(disabledContent.style.display).toBe('none'); + + // Click first tab + firstTab.click(); + await delay(10); + + const firstContent = document.querySelector(firstTabHash)!; + + expect(activeContent.style.display).toBe('none'); + expect(firstContent.style.display).not.toBe('none'); + expect(indicator.offsetLeft).toBe(firstTab.offsetLeft); + }); + + it("shouldn't hide active tab if clicked while active", async () => { + const normalTabs = document.querySelector('.tabs.normal')!; + const activeTab = normalTabs.querySelector('.active')!; + const activeTabHash = activeTab.getAttribute('href')!; + const indicator = normalTabs.querySelector('.indicator'); + + expect(indicator).not.toBeNull(); + + activeTab.click(); + await delay(10); + + const activeContent = document.querySelector(activeTabHash)!; + expect(activeContent.style.display).not.toBe('none'); + }); + + it('should horizontally scroll when too many tabs', () => { + const normalTabs = document.querySelector('.tabs.normal')!; + const tabsInstance = Tabs.getInstance(normalTabs); + // Mock container visible width (400px) and total scroll width (800px) + vi.spyOn(normalTabs, 'getBoundingClientRect').mockReturnValue({ + width: 400, + height: 50, + top: 0, + left: 0, + bottom: 50, + right: 400, + x: 0, + y: 0, + toJSON: () => {} + }); + Object.defineProperty(normalTabs, 'scrollWidth', { + configurable: true, + value: 800 + }); + // Trigger recalculation + tabsInstance._setTabsAndTabWidth(); + // Verify internal width state + expect(normalTabs.scrollWidth).toBeGreaterThan(tabsInstance._tabsWidth); + expect(tabsInstance._tabWidth).toBe(100); // 800px scrollWidth / 8 tabs + }); + + it('should programmatically switch tabs', async () => { + const normalTabs = document.querySelector('.tabs.normal')!; + const activeTab = normalTabs.querySelector('.active')!; + const activeTabHash = activeTab.getAttribute('href')!; + const firstTab = normalTabs.querySelector('li a')!; + const firstTabHash = firstTab.getAttribute('href')!; + const indicator = normalTabs.querySelector('.indicator')!; + const tabs = normalTabs.querySelectorAll('.tab a'); + + tabs.forEach((tab) => { + const tabHash = tab.getAttribute('href')!; + const contentEl = document.querySelector(tabHash)!; + + if (tabHash === activeTabHash) { + expect(contentEl.style.display).not.toBe('none'); + } else { + expect(contentEl.style.display).toBe('none'); + } + }); + + Tabs.getInstance(normalTabs)?.select('test1'); + await delay(10); + + const activeContent = document.querySelector(activeTabHash)!; + const firstContent = document.querySelector(firstTabHash)!; + + expect(activeContent.style.display).toBe('none'); + expect(firstContent.style.display).not.toBe('none'); + expect(indicator.offsetLeft).toBe(firstTab.offsetLeft); + }); + + it("shouldn't error if tab has no associated content", async () => { + document.querySelector('#test8')?.remove(); + + const tabNoContent = document.querySelector('[href="#test8"]')!; + expect(tabNoContent.classList.contains('active')).toBe(false); + + tabNoContent.click(); + await delay(10); + + expect(tabNoContent.classList.contains('active')).toBe(true); + }); + }); +}); diff --git a/components/tabs/tabs.ts b/components/tabs/tabs.ts index 50af294804..2a89f4a7e4 100644 --- a/components/tabs/tabs.ts +++ b/components/tabs/tabs.ts @@ -21,7 +21,7 @@ interface TabsOptions extends BaseOptions { /** * The maximum width of the screen, in pixels, * where the swipeable functionality initializes. - * @default infinity + * @default Infinity */ responsiveThreshold: number; } @@ -30,7 +30,7 @@ const _defaults: TabsOptions = { duration: 300, onShow: null, swipeable: false, - responsiveThreshold: Infinity // breakpoint for swipeable + responsiveThreshold: Infinity }; class Tabs extends Component { @@ -55,11 +55,13 @@ class Tabs extends Component { this._tabLinks = this.el.querySelectorAll('li.tab > a'); this._index = 0; this._setupActiveTabLink(); + if (this.options.swipeable) { this._setupSwipeableTabs(); } else { this._setupNormalTabs(); } + // Setup tabs indicator after content to ensure accurate widths this._setTabsAndTabWidth(); this._createIndicator(); @@ -70,23 +72,8 @@ class Tabs extends Component { return _defaults; } - /** - * Initializes instance of Tabs. - * @param el HTML element. - * @param options Component options. - */ static init(el: HTMLElement, options?: Partial): Tabs; - /** - * Initializes instances of Tabs. - * @param els HTML elements. - * @param options Component options. - */ static init(els: InitElements, options?: Partial): Tabs[]; - /** - * Initializes instances of Tabs. - * @param els HTML elements. - * @param options Component options. - */ static init( els: HTMLElement | InitElements, options: Partial = {} @@ -100,7 +87,9 @@ class Tabs extends Component { destroy() { this._removeEventHandlers(); - this._indicator.parentNode.removeChild(this._indicator); + if (this._indicator?.parentNode) { + this._indicator.parentNode.removeChild(this._indicator); + } if (this.options.swipeable) { this._teardownSwipeableTabs(); } else { @@ -109,9 +98,6 @@ class Tabs extends Component { this.el['M_Tabs'] = undefined; } - /** - * The index of tab that is currently shown. - */ get index() { return this._index; } @@ -119,23 +105,25 @@ class Tabs extends Component { _setupEventHandlers() { window.addEventListener('resize', this._handleWindowResize); this.el.addEventListener('click', this._handleTabClick); - // map vertical scrolling to horizontal scrolling because no scrollbar is shown on desktop - this.el.addEventListener('wheel', (event) => { - if (event.deltaY !== 0) { - event.preventDefault(); - this.el.scrollLeft += event.deltaY * 1; - } - }); + this.el.addEventListener('wheel', this._handleWheel); } _removeEventHandlers() { window.removeEventListener('resize', this._handleWindowResize); this.el.removeEventListener('click', this._handleTabClick); + this.el.removeEventListener('wheel', this._handleWheel); } + _handleWheel = (event: WheelEvent) => { + if (event.deltaY !== 0) { + event.preventDefault(); + this.el.scrollLeft += event.deltaY; + } + }; + _handleWindowResize = () => { this._setTabsAndTabWidth(); - if (this._tabWidth !== 0 && this._tabsWidth !== 0) { + if (this._tabWidth !== 0 && this._tabsWidth !== 0 && this._activeTabLink) { this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; } @@ -151,49 +139,46 @@ class Tabs extends Component { tab = tab.parentElement; } - // Handle click on tab link only - if (!tabLink || !tab.classList.contains('tab')) return; - // is disabled? + if (!tabLink || !tab?.classList.contains('tab')) return; if (tab.classList.contains('disabled')) { e.preventDefault(); return; } - // Act as regular link if target attribute is specified. if (tabLink.hasAttribute('target')) return; - // Make the old tab inactive. - this._activeTabLink.classList.remove('active'); + + this._activeTabLink?.classList.remove('active'); const _oldContent = this._content; - // Update the variables with the new link and content this._activeTabLink = tabLink; if (tabLink.hash) this._content = document.querySelector(tabLink.hash); this._tabLinks = this.el.querySelectorAll('li.tab > a'); - // Make the tab active + this._activeTabLink.classList.add('active'); const prevIndex = this._index; this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0); - // Swap content if (this.options.swipeable) { if (this._tabsCarousel) { this._tabsCarousel.set(this._index, () => { - if (typeof this.options.onShow === 'function') + if (typeof this.options.onShow === 'function') { this.options.onShow.call(this, this._content); + } }); } } else { if (this._content) { this._content.style.display = 'block'; this._content.classList.add('active'); - if (typeof this.options.onShow === 'function') + if (typeof this.options.onShow === 'function') { this.options.onShow.call(this, this._content); + } if (_oldContent && _oldContent !== this._content) { _oldContent.style.display = 'none'; _oldContent.classList.remove('active'); } } } - // Update widths after content is swapped (scrollbar bugfix) + this._setTabsAndTabWidth(); this._animateIndicator(prevIndex); e.preventDefault(); @@ -204,16 +189,17 @@ class Tabs extends Component { indicator.classList.add('indicator'); this.el.appendChild(indicator); this._indicator = indicator; - this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; - this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; + if (this._activeTabLink) { + this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px'; + this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; + } } _setupActiveTabLink() { - // If the location.hash matches one of the links, use that as the active tab. this._activeTabLink = Array.from(this._tabLinks).find( (a: HTMLAnchorElement) => a.getAttribute('href') === location.hash ); - // If no match is found, use the first link or any with class 'active' as the initial active tab. + if (!this._activeTabLink) { let activeTabLink = this.el.querySelector('li.tab a.active'); if (!activeTabLink) { @@ -221,43 +207,49 @@ class Tabs extends Component { } this._activeTabLink = activeTabLink as HTMLAnchorElement; } + Array.from(this._tabLinks).forEach((a: HTMLAnchorElement) => a.classList.remove('active')); - this._activeTabLink.classList.add('active'); - this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0); - if (this._activeTabLink && this._activeTabLink.hash) { - this._content = document.querySelector(this._activeTabLink.hash); - if (this._content) this._content.classList.add('active'); + if (this._activeTabLink) { + this._activeTabLink.classList.add('active'); + this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0); + if (this._activeTabLink.hash) { + this._content = document.querySelector(this._activeTabLink.hash); + if (this._content) this._content.classList.add('active'); + } } } _setupSwipeableTabs() { - // Change swipeable according to responsive threshold - if (window.innerWidth > this.options.responsiveThreshold) this.options.swipeable = false; + if (window.innerWidth > this.options.responsiveThreshold) { + this.options.swipeable = false; + return; + } - const tabsContent = []; + const tabsContent: HTMLElement[] = []; this._tabLinks.forEach((a) => { if (a.hash) { - const currContent = document.querySelector(a.hash); - currContent.classList.add('carousel-item'); - tabsContent.push(currContent); + const currContent = document.querySelector(a.hash) as HTMLElement; + if (currContent) { + currContent.classList.add('carousel-item'); + tabsContent.push(currContent); + } } }); - // Create Carousel-Wrapper around Tab-Contents + if (tabsContent.length === 0) return; + const tabsWrapper = document.createElement('div'); tabsWrapper.classList.add('tabs-content', 'carousel', 'carousel-slider'); - // Wrap around tabsContent[0].parentElement.insertBefore(tabsWrapper, tabsContent[0]); tabsContent.forEach((tabContent) => { tabsWrapper.appendChild(tabContent); tabContent.style.display = ''; }); - // Keep active tab index to set initial carousel slide - const tab = this._activeTabLink.parentElement; - const activeTabIndex = Array.from(tab.parentNode.children).indexOf(tab); + const tab = this._activeTabLink?.parentElement; + const activeTabIndex = tab ? Array.from(tab.parentNode.children).indexOf(tab) : 0; this._tabsCarousel = Carousel.init(tabsWrapper, { fullWidth: true, @@ -265,39 +257,42 @@ class Tabs extends Component { onCycleTo: (item) => { const prevIndex = this._index; this._index = Array.from(item.parentNode.children).indexOf(item); - this._activeTabLink.classList.remove('active'); + this._activeTabLink?.classList.remove('active'); this._activeTabLink = Array.from(this._tabLinks)[this._index]; - this._activeTabLink.classList.add('active'); + this._activeTabLink?.classList.add('active'); this._animateIndicator(prevIndex); - if (typeof this.options.onShow === 'function') + if (typeof this.options.onShow === 'function') { this.options.onShow.call(this, this._content); + } } }); - // Set initial carousel slide to active tab + this._tabsCarousel.set(activeTabIndex); } _teardownSwipeableTabs() { + if (!this._tabsCarousel) return; const tabsWrapper = this._tabsCarousel.el; this._tabsCarousel.destroy(); - // Unwrap - tabsWrapper.append(tabsWrapper.parentElement); + + // Move children back out to the parent container + while (tabsWrapper.firstChild) { + tabsWrapper.parentElement.insertBefore(tabsWrapper.firstChild, tabsWrapper); + } tabsWrapper.remove(); } _setupNormalTabs() { - // Hide Tabs Content Array.from(this._tabLinks).forEach((a) => { if (a === this._activeTabLink) return; - if ((a).hash) { - const currContent = document.querySelector((a).hash); - if (currContent) (currContent).style.display = 'none'; + if (a.hash) { + const currContent = document.querySelector(a.hash) as HTMLElement; + if (currContent) currContent.style.display = 'none'; } }); } _teardownNormalTabs() { - // show Tabs Content this._tabLinks.forEach((a) => { if (a.hash) { const currContent = document.querySelector(a.hash) as HTMLElement; @@ -308,7 +303,10 @@ class Tabs extends Component { _setTabsAndTabWidth() { this._tabsWidth = this.el.getBoundingClientRect().width; - this._tabWidth = Math.max(this._tabsWidth, this.el.scrollWidth) / this._tabLinks.length; + this._tabWidth = + this._tabLinks.length > 0 + ? Math.max(this._tabsWidth, this.el.scrollWidth) / this._tabLinks.length + : 0; } _calcRightPos(el: HTMLElement) { @@ -319,24 +317,21 @@ class Tabs extends Component { return Math.floor(el.offsetLeft); } - /** - * Recalculate tab indicator position. This is useful when - * the indicator position is not correct. - */ updateTabIndicator() { this._setTabsAndTabWidth(); this._animateIndicator(this._index); } _animateIndicator(prevIndex: number) { - let leftDelay = 0, - rightDelay = 0; + if (!this._indicator || !this._activeTabLink) return; + + let leftDelay = 0; + let rightDelay = 0; const isMovingLeftOrStaying = this._index - prevIndex >= 0; if (isMovingLeftOrStaying) leftDelay = 90; else rightDelay = 90; - // in v1: easeOutQuad this._indicator.style.transition = ` left ${this.options.duration}ms ease-out ${leftDelay}ms, right ${this.options.duration}ms ease-out ${rightDelay}ms`; @@ -345,15 +340,11 @@ class Tabs extends Component { this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px'; } - /** - * Show tab content that corresponds to the tab with the id. - * @param tabId The id of the tab that you want to switch to. - */ select(tabId: string) { const tab = Array.from(this._tabLinks).find( (a: HTMLAnchorElement) => a.getAttribute('href') === '#' + tabId ); - if (tab) (tab).click(); + if (tab) tab.click(); } } diff --git a/components/tooltip/_tooltip.scss b/components/tooltip/___del_tooltip.scss similarity index 100% rename from components/tooltip/_tooltip.scss rename to components/tooltip/___del_tooltip.scss diff --git a/package.json b/package.json index 36717d05ee..31279b259f 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ ], "scripts": { "lint": "eslint .", - "test": "jasmine-browser-runner runSpecs --config=jasmine.json", + "test": "vitest", "build": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript", "build-storybook": "storybook build", "build-examples": "examples/compile.sh", @@ -47,8 +47,7 @@ "preversion": "npm run lint && npm test", "version": "npm run build -- --environment BUILD:release && node compress.mjs && git add .", "storybook": "storybook dev -p 6006", - "demo": "live-server", - "vitest": "vitest" + "demo": "live-server" }, "lint-staged": { "js/*.js": [ diff --git a/sass/materialize.scss b/sass/materialize.scss index 910f8f4a5f..b2a6be8352 100644 --- a/sass/materialize.scss +++ b/sass/materialize.scss @@ -23,7 +23,7 @@ @forward '../components/card/cards'; @forward '../components/snackbar/toast'; @forward '../components/tabs/tabs'; -@forward '../components/tooltip/tooltip'; +@forward '../components/tooltip/tooltip.css'; @forward '../components/dropdown/dropdown'; @forward '../components/list/collection'; @forward '../components/list/list'; From f821e79a551083860cc54c06920560ac3807b240 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 10:38:17 +0200 Subject: [PATCH 16/60] test(snackbar): convert to vitest --- components/snackbar/___toastSpec.js | 121 ----------------------- components/snackbar/snackbar.test.ts | 132 +++++++++++++++++++++++++ components/snackbar/toasts.ts | 140 ++++++++++++++++----------- 3 files changed, 216 insertions(+), 177 deletions(-) delete mode 100644 components/snackbar/___toastSpec.js create mode 100644 components/snackbar/snackbar.test.ts diff --git a/components/snackbar/___toastSpec.js b/components/snackbar/___toastSpec.js deleted file mode 100644 index 3ec28e6940..0000000000 --- a/components/snackbar/___toastSpec.js +++ /dev/null @@ -1,121 +0,0 @@ -describe('Toasts:', () => { - describe('Toast javascript functions', () => { - it('should display and remove a toast', (done) => { - const instance = new M.Toast({ - text: 'Test toast', - inDuration: 20, - displayLength: 100, - outDuration: 20 - }); - const wrapperWasCreated = document.querySelectorAll('#toast-container').length === 1; - expect(wrapperWasCreated).toEqual(true, 'because toast was created'); - const toast = instance.el; - setTimeout(() => { - // is visible? - //const toasts = document.querySelectorAll('.toast'); - //const toast = toasts[0]; - //expect(toasts.length).toBe(1, 'because one toast was created'); - expect(toast.getAttribute('role')).toBe('alert'); - expect(toast.getAttribute('aria-live')).toBe('assertive'); - expect(toast.getAttribute('aria-atomic')).toBe('true'); - expect(toast).toBeVisible(); - expect(toast.innerText).toBe('Test toast'); - setTimeout(() => { - //const toasts = document.querySelectorAll('.toast'); - expect(toast).toBeVisible(); - //expect(toasts.length).toBe(1, 'because toast duration still on going'); - setTimeout(() => { - //const toasts = document.querySelectorAll('.toast'); - //console.log(); - expect(typeof toast.el).toBe('undefined', 'because toast should be removed by now'); - done(); - }, 150); - }, 30); - }, 10); - }); - - // it('Opens a toast with HTML content', function(done) { - // let toastContent = document.createElement("span"); - // toastContent.innerText = 'I am toast content'; - // M.toast({html: toastContent.outerHTML, displayLength: 400}); - // let toastSpan = document.querySelector('.toast span'); - // expect(toastSpan.innerText).toBe('I am toast content'); - // expect(toastSpan.innerText).not.toBe('I am toast'); - // setTimeout(function() { - // done(); - // }, 490); - // }); - - it('Toasts should call the callback function when dismissed', (done) => { - let wasCalled = false; - const callback = () => (wasCalled = true); - new M.Toast({ - text: 'I am a toast', - inDuration: 10, - displayLength: 50, - outDuration: 10, - completeCallback: callback - }); - setTimeout(() => { - expect(wasCalled).toBe(true, 'because the callback set it to true'); - done(); - }, 100); - }); - - it('should apply classes to toast', (done) => { - new M.Toast({ - text: 'Hi', - displayLength: 100, - inDuration: 10, - outDuration: 10, - classes: 'round flat' - }); - setTimeout(() => { - const toastFlat = document.querySelectorAll('.toast.round.flat'); - expect(toastFlat.length).toBe(1, 'because the class parameter was passed with two classes'); - done(); - }, 20); - }); - }); - - describe('Toast _container null guard', () => { - afterEach(() => { - // Reset shared static state so other specs are unaffected - M.Toast.dismissAll(); - M.Toast._removeContainer(); - }); - - it('should not throw when _removeContainer is called with a null container', () => { - M.Toast._container = null; - expect(() => M.Toast._removeContainer()).not.toThrow(); - expect(M.Toast._container).toBeNull('because there was no container to remove'); - }); - - it('should not throw when _removeContainer is called twice', () => { - // First call removes a freshly created container, second call hits the guard. - M.Toast._createContainer(); - expect(M.Toast._container).not.toBeNull('because a container was just created'); - - expect(() => M.Toast._removeContainer()).not.toThrow(); - expect(M.Toast._container).toBeNull('because the container was just removed'); - - expect(() => M.Toast._removeContainer()).not.toThrow('because the guard protects the second call'); - expect(M.Toast._container).toBeNull(); - }); - - it('should not throw building a toast while _container is null', () => { - // Create a first toast so the container exists and _toasts is non-empty, - // then null the container to force the inconsistent state the guard handles - // (a second toast skips _createContainer because _toasts.length !== 0). - const first = new M.Toast({ text: 'First', displayLength: 50, inDuration: 10, outDuration: 10 }); - expect(first.el).toBeDefined(); - M.Toast._container = null; - - let instance; - expect(() => { - instance = new M.Toast({ text: 'No container', displayLength: 50, inDuration: 10, outDuration: 10 }); - }).not.toThrow('because _createToast guards the null container'); - expect(instance.el).toBeDefined('because the toast element is still created without a container'); - }); - }); -}); diff --git a/components/snackbar/snackbar.test.ts b/components/snackbar/snackbar.test.ts new file mode 100644 index 0000000000..1c491d0b4a --- /dev/null +++ b/components/snackbar/snackbar.test.ts @@ -0,0 +1,132 @@ +// @vitest-environment happy-dom + +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { Toast } from './toasts'; + +describe('Toasts:', () => { + beforeEach(() => { + vi.useFakeTimers(); + document.body.innerHTML = ''; + }); + + afterEach(() => { + Toast.dismissAll(); + Toast._removeContainer(); + vi.restoreAllMocks(); + vi.useRealTimers(); + }); + + describe('Toast javascript functions', () => { + it('should display and remove a toast', () => { + const instance = new Toast({ + text: 'Test toast', + inDuration: 20, + displayLength: 100, + outDuration: 20 + }); + + const wrapperWasCreated = document.querySelectorAll('#toast-container').length === 1; + expect(wrapperWasCreated).toBe(true); + + const toast = instance.el; + + // Advance timers past inDuration animation trigger + vi.advanceTimersByTime(10); + expect(toast.getAttribute('role')).toBe('alert'); + expect(toast.getAttribute('aria-live')).toBe('assertive'); + expect(toast.getAttribute('aria-atomic')).toBe('true'); + expect(toast.innerText).toBe('Test toast'); + expect(document.body.contains(toast)).toBe(true); + + // Advance timers to middle of display duration + vi.advanceTimersByTime(30); + expect(document.body.contains(toast)).toBe(true); + + // Advance timers past displayLength + outDuration to trigger removal + vi.advanceTimersByTime(150); + expect(document.body.contains(toast)).toBe(false); + }); + + it('Toasts should call the callback function when dismissed', () => { + let wasCalled = false; + const callback = () => { + wasCalled = true; + }; + + new Toast({ + text: 'I am a toast', + inDuration: 10, + displayLength: 50, + outDuration: 10, + completeCallback: callback + }); + + // Advance past total duration (50 + 10 = 60ms) + vi.advanceTimersByTime(100); + expect(wasCalled).toBe(true); + }); + + it('should apply classes to toast', () => { + new Toast({ + text: 'Hi', + displayLength: 100, + inDuration: 10, + outDuration: 10, + classes: 'round flat' + }); + + vi.advanceTimersByTime(20); + const toastFlat = document.querySelectorAll('.toast.round.flat'); + expect(toastFlat.length).toBe(1); + }); + }); + + describe('Toast _container null guard', () => { + afterEach(() => { + Toast.dismissAll(); + Toast._removeContainer(); + }); + + it('should not throw when _removeContainer is called with a null container', () => { + (Toast as any)._container = null; + expect(() => Toast._removeContainer()).not.toThrow(); + expect((Toast as any)._container).toBeNull(); + }); + + it('should not throw when _removeContainer is called twice', () => { + Toast._createContainer(); + expect((Toast as any)._container).not.toBeNull(); + + expect(() => Toast._removeContainer()).not.toThrow(); + expect((Toast as any)._container).toBeNull(); + + expect(() => Toast._removeContainer()).not.toThrow(); + expect((Toast as any)._container).toBeNull(); + }); + + it('should not throw building a toast while _container is null', () => { + const first = new Toast({ + text: 'First', + displayLength: 50, + inDuration: 10, + outDuration: 10 + }); + expect(first.el).toBeDefined(); + + // Force null container state + (Toast as any)._container = null; + + let instance: Toast | undefined; + expect(() => { + instance = new Toast({ + text: 'No container', + displayLength: 50, + inDuration: 10, + outDuration: 10 + }); + }).not.toThrow(); + + expect(instance?.el).toBeDefined(); + }); + }); +}); diff --git a/components/snackbar/toasts.ts b/components/snackbar/toasts.ts index 40b22c189c..93e7e1199f 100644 --- a/components/snackbar/toasts.ts +++ b/components/snackbar/toasts.ts @@ -7,7 +7,7 @@ export interface ToastOptions extends BaseOptions { */ text: string; /** - * Element Id for the tooltip. + * Element Id for the tooltip/template. * @default "" */ toastId?: string; @@ -35,9 +35,9 @@ export interface ToastOptions extends BaseOptions { * Callback function called when toast is dismissed. * @default null */ - completeCallback: () => void; + completeCallback?: (() => void) | null; /** - * The percentage of the toast's width it takes fora drag + * The percentage of the toast's width it takes for a drag * to dismiss a Toast. * @default 0.8 */ @@ -46,6 +46,7 @@ export interface ToastOptions extends BaseOptions { const _defaults: ToastOptions = { text: '', + toastId: '', displayLength: 4000, inDuration: 300, outDuration: 375, @@ -56,7 +57,7 @@ const _defaults: ToastOptions = { export class Toast { /** The toast element. */ - el: HTMLElement; + el!: HTMLElement; /** * The remaining amount of time in ms that the toast * will stay before dismissal. @@ -68,19 +69,19 @@ export class Toast { panning: boolean; options: ToastOptions; message: string; - counterInterval: NodeJS.Timeout | number; - wasSwiped: boolean; - startingXPos: number; - xPos: number; - time: number; - deltaX: number; - velocityX: number; - - static _toasts: Toast[]; - private static _container: HTMLElement | null; - static _draggedToast: Toast; - - constructor(options: Partial) { + counterInterval?: ReturnType; + wasSwiped: boolean = false; + startingXPos: number = 0; + xPos: number = 0; + time: number = 0; + deltaX: number = 0; + velocityX: number = 0; + + static _toasts: Toast[] = []; + private static _container: HTMLElement | null = null; + static _draggedToast: Toast | null = null; + + constructor(options?: Partial) { this.options = { ...Toast.defaults, ...options @@ -88,13 +89,15 @@ export class Toast { this.message = this.options.text; this.panning = false; this.timeRemaining = this.options.displayLength; + if (Toast._toasts.length === 0) { Toast._createContainer(); } + // Create new toast Toast._toasts.push(this); const toastElement = this._createToast(); - toastElement['M_Toast'] = this; + (toastElement as any)['M_Toast'] = this; this.el = toastElement; this._animateIn(); this._setTimer(); @@ -105,19 +108,21 @@ export class Toast { } static getInstance(el: HTMLElement): Toast { - return el['M_Toast']; + return (el as any)['M_Toast']; } static _createContainer() { const container = document.createElement('div'); container.setAttribute('id', 'toast-container'); - // Add event handler + + // Add event handlers container.addEventListener('touchstart', Toast._onDragStart); container.addEventListener('touchmove', Toast._onDragMove); container.addEventListener('touchend', Toast._onDragEnd); container.addEventListener('mousedown', Toast._onDragStart); document.addEventListener('mousemove', Toast._onDragMove); document.addEventListener('mouseup', Toast._onDragEnd); + document.body.appendChild(container); Toast._container = container; } @@ -132,9 +137,11 @@ export class Toast { } static _onDragStart(e: TouchEvent | MouseEvent) { - if (e.target && (e.target).closest('.toast')) { - const toastElem = (e.target).closest('.toast'); - const toast: Toast = toastElem['M_Toast']; + if (e.target && (e.target as HTMLElement).closest('.toast')) { + const toastElem = (e.target as HTMLElement).closest('.toast') as HTMLElement; + const toast: Toast = (toastElem as any)['M_Toast']; + if (!toast) return; + toast.panning = true; Toast._draggedToast = toast; toast.el.classList.add('panning'); @@ -146,23 +153,26 @@ export class Toast { } static _onDragMove(e: TouchEvent | MouseEvent) { - if (!!Toast._draggedToast) { + if (Toast._draggedToast) { e.preventDefault(); const toast = Toast._draggedToast; - toast.deltaX = Math.abs(toast.xPos - Toast._xPos(e)); - toast.xPos = Toast._xPos(e); - toast.velocityX = toast.deltaX / (Date.now() - toast.time); + const currentX = Toast._xPos(e); + + toast.deltaX = Math.abs(toast.xPos - currentX); + toast.xPos = currentX; + toast.velocityX = toast.deltaX / (Date.now() - toast.time || 1); toast.time = Date.now(); const totalDeltaX = toast.xPos - toast.startingXPos; const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; + toast.el.style.transform = `translateX(${totalDeltaX}px)`; toast.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString(); } } static _onDragEnd() { - if (!!Toast._draggedToast) { + if (Toast._draggedToast) { const toast = Toast._draggedToast; toast.panning = false; toast.el.classList.remove('panning'); @@ -171,12 +181,11 @@ export class Toast { const activationDistance = toast.el.offsetWidth * toast.options.activationPercent; const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || toast.velocityX > 1; - // Remove toast if (shouldBeDismissed) { toast.wasSwiped = true; toast.dismiss(); - // Animate toast back to original position } else { + // Animate toast back to original position toast.el.style.transition = 'transform .2s, opacity .2s'; toast.el.style.transform = ''; toast.el.style.opacity = ''; @@ -185,40 +194,58 @@ export class Toast { } } - static _xPos(e: TouchEvent | MouseEvent) { - if (e.type.startsWith('touch') && (e as TouchEvent).targetTouches.length >= 1) { - return (e as TouchEvent).targetTouches[0].clientX; + static _xPos(e: TouchEvent | MouseEvent): number { + if (e.type.startsWith('touch')) { + const touchEvent = e as TouchEvent; + if (touchEvent.targetTouches && touchEvent.targetTouches.length >= 1) { + return touchEvent.targetTouches[0].clientX; + } + if (touchEvent.changedTouches && touchEvent.changedTouches.length >= 1) { + return touchEvent.changedTouches[0].clientX; + } } - // mouse event return (e as MouseEvent).clientX; } /** - * dismiss all toasts. + * Dismiss all active toasts. */ static dismissAll() { - for (const toastIndex in Toast._toasts) { - Toast._toasts[toastIndex].dismiss(); + const toastsCopy = [...Toast._toasts]; + for (const toast of toastsCopy) { + toast.dismiss(); } } - _createToast() { + _createToast(): HTMLElement { let toast: HTMLElement = this.options.toastId - ? document.getElementById(this.options.toastId) + ? (document.getElementById(this.options.toastId) as HTMLElement) : document.createElement('div'); + if (toast instanceof HTMLTemplateElement) { - const node = (toast as HTMLTemplateElement).content.cloneNode(true); + const node = toast.content.cloneNode(true); toast = (node as HTMLElement).firstElementChild as HTMLElement; + } else if (this.options.toastId && toast) { + toast = toast.cloneNode(true) as HTMLElement; + toast.removeAttribute('id'); + } + + if (!toast) { + toast = document.createElement('div'); } + toast.classList.add('toast'); toast.setAttribute('role', 'alert'); toast.setAttribute('aria-live', 'assertive'); toast.setAttribute('aria-atomic', 'true'); + // Add custom classes onto toast if (this.options.classes.length > 0) { - toast.classList.add(...this.options.classes.split(' ')); + toast.classList.add(...this.options.classes.split(' ').filter(Boolean)); } + if (this.message) toast.innerText = this.message; + if (Toast._container) { Toast._container.appendChild(toast); } @@ -226,10 +253,8 @@ export class Toast { } _animateIn() { - // Animate toast in this.el.style.display = ''; this.el.style.opacity = '0'; - // easeOutCubic this.el.style.transition = ` top ${this.options.inDuration}ms ease, opacity ${this.options.inDuration}ms ease @@ -241,17 +266,14 @@ export class Toast { } /** - * Create setInterval which automatically removes toast when timeRemaining >= 0 - * has been reached. + * Create setInterval which automatically removes toast when timeRemaining <= 0 */ _setTimer() { if (this.timeRemaining !== Infinity) { this.counterInterval = setInterval(() => { - // If toast is not being dragged, decrease its time remaining if (!this.panning) { this.timeRemaining -= 20; } - // Animate toast out if (this.timeRemaining <= 0) { this.dismiss(); } @@ -263,7 +285,10 @@ export class Toast { * Dismiss toast with animation. */ dismiss() { - clearInterval(this.counterInterval); + if (this.counterInterval) { + clearInterval(this.counterInterval); + } + const activationDistance = this.el.offsetWidth * this.options.activationPercent; if (this.wasSwiped) { @@ -272,7 +297,6 @@ export class Toast { this.el.style.opacity = '0'; } - // easeOutExpo this.el.style.transition = ` margin ${this.options.outDuration}ms ease, opacity ${this.options.outDuration}ms ease`; @@ -287,13 +311,17 @@ export class Toast { if (typeof this.options.completeCallback === 'function') { this.options.completeCallback(); } - // Remove toast from DOM - if (this.el.id != this.options.toastId) { - this.el.remove(); - Toast._toasts.splice(Toast._toasts.indexOf(this), 1); - if (Toast._toasts.length === 0) { - Toast._removeContainer(); - } + + // Remove toast element and clean up internal state + this.el.remove(); + + const index = Toast._toasts.indexOf(this); + if (index !== -1) { + Toast._toasts.splice(index, 1); + } + + if (Toast._toasts.length === 0) { + Toast._removeContainer(); } }, this.options.outDuration); } From 0bd988dae4f38b0ee907ca1ede2e469f45d55fc9 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 10:48:17 +0200 Subject: [PATCH 17/60] fix(divider): add builder --- components/divider/divider.mjs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 components/divider/divider.mjs diff --git a/components/divider/divider.mjs b/components/divider/divider.mjs new file mode 100644 index 0000000000..94ab98100d --- /dev/null +++ b/components/divider/divider.mjs @@ -0,0 +1,10 @@ +import { Component } from '../atomic/component.mjs'; + +class Divider extends Component { + constructor(options) { + super(options); + this.addClassname('divider'); + } +} + +export { Divider }; From 23d1a2bede78fd855f6c38fe84548cd93e0d6beb Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 11:08:51 +0200 Subject: [PATCH 18/60] fix: testing js tooltip on blog in examples --- components/atomic/component.mjs | 17 ++++++++++------- components/atomic/page.mjs | 28 +++++++++++++++++++++------- examples/html/blog.html | 7 +++++-- examples/html/landingpage.html | 2 ++ examples/html/portfolio.html | 2 ++ examples/src/blog.js | 11 ++++++++--- 6 files changed, 48 insertions(+), 19 deletions(-) diff --git a/components/atomic/component.mjs b/components/atomic/component.mjs index fce33b6f50..8d51846f49 100644 --- a/components/atomic/component.mjs +++ b/components/atomic/component.mjs @@ -10,16 +10,19 @@ class Component { this.#children = []; this.#classNames = []; - if (typeof options === 'object' && options !== null && options.children) { - if (typeof options.children === 'string') { - this.#children = options.children; + if (typeof options === 'object' && options !== null) { + // children + if (options.children) { + if (typeof options.children === 'string') { + this.#children = options.children; + return; + } + const kids = Array.isArray(options.children) ? options.children : [options.children]; + kids.forEach((c) => this.addChild(c)); return; } - const kids = Array.isArray(options.children) ? options.children : [options.children]; - kids.forEach((c) => this.addChild(c)); - return; } - this.#children = options; + this.#children = options; // TODO: Maybe do not do this } setChildren(children) { diff --git a/components/atomic/page.mjs b/components/atomic/page.mjs index a6d30ebcb1..ff3022433d 100644 --- a/components/atomic/page.mjs +++ b/components/atomic/page.mjs @@ -3,24 +3,35 @@ import { Component } from './component.mjs'; class Page extends Component { #title; #metaDescription; - #styleList = []; - #css = []; + #css; + #cssUrls; + #scripts; + #scriptUrls; constructor(options) { super(options); this.setTagName('html'); if (options.title) this.setTitle(options.title); + this.#cssUrls = []; + this.#scriptUrls = []; + this.#css = []; + this.#scripts = []; } addStyleUrl(url) { - this.#styleList.push(url); + this.#cssUrls.push(url); return this; } addStyle(css) { this.#css.push(css); return this; } - addJavascriptUrl() { + addJavascriptUrl(url) { + this.#scriptUrls.push(url); + return this; + } + addJavascript(script) { + this.#scripts.push(script); return this; } setTitle(title) { @@ -35,11 +46,12 @@ class Page extends Component { toHTML() { return ` ${this.#title} - ${this.#styleList + ${this.#cssUrls .map( - (s) => `` + (url) => + `` ) - .join('')} + .join('\n')} ${this.#css.map((s) => ``).join('\n')} @@ -47,6 +59,8 @@ class Page extends Component {
${super.toHTML()}
+ ${this.#scriptUrls.map((url) => ``).join('\n')} + ${this.#scripts.map((s) => ``).join('\n')} `; } } diff --git a/examples/html/blog.html b/examples/html/blog.html index 051d5f42e3..b4873c1f47 100644 --- a/examples/html/blog.html +++ b/examples/html/blog.html @@ -1,6 +1,7 @@ Materialize Web Blog - + + `).join('\n')} - - - -
- ${super.toHTML()} -
- ${this.#scriptUrls.map((url) => ``).join('\n')} - ${this.#scripts.map((s) => ``).join('\n')} - `; + return ` + + + + + + ${this.#title} + ${this.#cssUrls + .map( + (url) => `` + ) + .join('\n')} + ${this.#css.map((s) => ``).join('\n')} + + +
+ ${super.toHTML()} +
+ ${this.#scriptUrls.map((url) => ``).join('\n')} + ${this.#scripts.map((s) => ``).join('\n')} + +`; } } diff --git a/examples/html/blog.html b/examples/html/blog.html index b4873c1f47..cf8bdea7d8 100644 --- a/examples/html/blog.html +++ b/examples/html/blog.html @@ -1,18 +1,22 @@ - - Materialize Web Blog - + + + + + + + Materialize Web Blog + - - - - -
-

Materialize Web Blog

+ + +
+

Materialize Web Blog

01/01/2026 posted by Daniel

Crafting Sleek, Responsive Interfaces with MaterializeWeb

In the fast-evolving landscape of web development, building clean, responsive, and intuitive user interfaces remains a top priority. While major CSS frameworks like Bootstrap have long dominated the scene, MaterializeWeb—the community-driven evolution of MaterializeCSS—offers a refreshing design philosophy anchored directly in Google’s Material Design principles.

@@ -29,7 +33,8 @@

Why Choose It for Your Next Project?

If you want your web applications to mirror the sleek, unified visual identity of modern mobile apps without spending weeks writing custom styles, MaterializeWeb is an outstanding choice. It strikes an ideal balance between aesthetic polish and developer efficiency, making it perfect for rapid prototyping and production-ready sites alike.

Give MaterializeWeb a try on your next project to experience how effortless modern visual design can be!

2 or 3-column masonry grid showing article thumbnails, titles, and publication dates
This is a test Landingpage. ok it can produce nested html too...
Or you can go to the Portfolio
Sidebar or navigation dropdowns ("Tech," "Lifestyle")
-
- - - +
+ + + + diff --git a/examples/html/landingpage.html b/examples/html/landingpage.html index 58d1331545..8dcf43af47 100644 --- a/examples/html/landingpage.html +++ b/examples/html/landingpage.html @@ -1,15 +1,20 @@ - - My Landingpage - - - - - -
-

Landing Page

Hero Section
A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
+ + + + + + + My Landingpage + + + + +
+

Landing Page

Hero Section
A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.
You can also checkout the Blog
Hello, this is my landing page!
-
- - - +
+ + + + diff --git a/examples/html/portfolio.html b/examples/html/portfolio.html index 9f91e52857..f6c4152506 100644 --- a/examples/html/portfolio.html +++ b/examples/html/portfolio.html @@ -1,13 +1,18 @@ - - My Portfolio - - - - - -
-

My Portfolio

Hello, this is my portfolio. You can also checkout the Blog
Sidebar
-
- - - + + + + + + + My Portfolio + + + + +
+

My Portfolio

Hello, this is my portfolio. You can also checkout the Blog
Sidebar
+
+ + + + From 93fe4289fcb3b3a572bb403c9cf4bd82ea8f0ace Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 11:26:28 +0200 Subject: [PATCH 20/60] fix: page and html generation --- components/atomic/component.mjs | 4 ++-- components/atomic/page.mjs | 5 +++-- examples/html/blog.html | 21 ++++++++++++++++++--- examples/html/landingpage.html | 13 +++++++++++-- examples/html/portfolio.html | 9 ++++++++- examples/src/blog.js | 2 +- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/components/atomic/component.mjs b/components/atomic/component.mjs index 8d51846f49..0eca34f826 100644 --- a/components/atomic/component.mjs +++ b/components/atomic/component.mjs @@ -64,10 +64,10 @@ class Component { if (Array.isArray(this.#children)) { const innerHTML = this.#children.map((child) => child.toHTML()).join(''); - return `<${this.#tagname}${classAttr}${otherAttrs}>${innerHTML}`; + return `<${this.#tagname}${classAttr}${otherAttrs}>\n${innerHTML}\n`; } - return `<${this.#tagname}${classAttr}${otherAttrs}>${this.#children ?? ''}`; + return `<${this.#tagname}${classAttr}${otherAttrs}>${this.#children ?? ''}\n`; } toDOM() { diff --git a/components/atomic/page.mjs b/components/atomic/page.mjs index 535b6249ac..9e7d5d3960 100644 --- a/components/atomic/page.mjs +++ b/components/atomic/page.mjs @@ -11,7 +11,7 @@ class Page extends Component { constructor(options) { super(options); - this.setTagName('html'); + //this.setTagName('html'); if (options.title) this.setTitle(options.title); this.#langCode = 'en'; this.#cssUrls = []; @@ -46,6 +46,7 @@ class Page extends Component { } // override toHTML() { + const content = super.toHTML(); return ` @@ -62,7 +63,7 @@ class Page extends Component {
- ${super.toHTML()} + ${content}
${this.#scriptUrls.map((url) => ``).join('\n')} ${this.#scripts.map((s) => ``).join('\n')} diff --git a/examples/html/blog.html b/examples/html/blog.html index cf8bdea7d8..7ec934a27b 100644 --- a/examples/html/blog.html +++ b/examples/html/blog.html @@ -16,7 +16,16 @@
-

Materialize Web Blog

+
+
+

Materialize Web Blog

+
+ + +

01/01/2026 posted by Daniel

Crafting Sleek, Responsive Interfaces with MaterializeWeb

In the fast-evolving landscape of web development, building clean, responsive, and intuitive user interfaces remains a top priority. While major CSS frameworks like Bootstrap have long dominated the scene, MaterializeWeb—the community-driven evolution of MaterializeCSS—offers a refreshing design philosophy anchored directly in Google’s Material Design principles.

@@ -31,8 +40,14 @@

Key Features and Benefits

Why Choose It for Your Next Project?

If you want your web applications to mirror the sleek, unified visual identity of modern mobile apps without spending weeks writing custom styles, MaterializeWeb is an outstanding choice. It strikes an ideal balance between aesthetic polish and developer efficiency, making it perfect for rapid prototyping and production-ready sites alike.

-

Give MaterializeWeb a try on your next project to experience how effortless modern visual design can be!

2 or 3-column masonry grid showing article thumbnails, titles, and publication dates
This is a test Landingpage. ok it can produce nested html too...
- Or you can go to the Portfolio
Sidebar or navigation dropdowns ("Tech," "Lifestyle")
+

Give MaterializeWeb a try on your next project to experience how effortless modern visual design can be!

+
2 or 3-column masonry grid showing article thumbnails, titles, and publication dates
+ +This is a test Landingpage. ok it can produce nested html too...
+ Or you can go to the Portfolio
+
Sidebar or navigation dropdowns ("Tech," "Lifestyle")
+
+ diff --git a/examples/html/landingpage.html b/examples/html/landingpage.html index 8dcf43af47..11c7746f30 100644 --- a/examples/html/landingpage.html +++ b/examples/html/landingpage.html @@ -10,9 +10,18 @@
-

Landing Page

Hero Section
A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
+
+
+

Landing Page

+
+
+
Hero Section
+
A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.
- You can also checkout the Blog
Hello, this is my landing page!
+ You can also checkout the Blog
+
Hello, this is my landing page!
+
+
diff --git a/examples/html/portfolio.html b/examples/html/portfolio.html index f6c4152506..d15f929609 100644 --- a/examples/html/portfolio.html +++ b/examples/html/portfolio.html @@ -10,7 +10,14 @@
-

My Portfolio

Hello, this is my portfolio. You can also checkout the Blog
Sidebar
+
+
+

My Portfolio

+
+
Hello, this is my portfolio. You can also checkout the Blog
+
Sidebar
+
+
diff --git a/examples/src/blog.js b/examples/src/blog.js index e04efaa7b1..ee3bcbcd10 100644 --- a/examples/src/blog.js +++ b/examples/src/blog.js @@ -39,7 +39,7 @@ const blogPage = new Page({ // TODO: use NavigationBar Component new Container({ children: new Text('Materialize Web Blog').setTagName('p').addClassname('py-3') - }), + }).addClassname('wrapper-1'), new Container({ children: [ From 6efb5433e5b4e635c1a01940aab71774d87158d8 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Wed, 12 Aug 2026 13:45:37 +0200 Subject: [PATCH 21/60] refactor: dropdown --- components/button/examples.iso.js | 18 - .../{buttons.ts => floatingactionbutton.ts} | 0 components/button/test-button.mjs | 16 - components/divider/divider.mjs | 1 + .../{_dropdown.scss => ____dropdown.scss} | 0 components/dropdown/___dropdownSpec.js | 108 ---- components/dropdown/dropdown.css | 60 +++ components/dropdown/dropdown.mjs | 1 + components/dropdown/dropdown.ts | 481 +++++------------- components/dropdown/readme.md | 22 + examples/counter-app.iso.js | 64 +++ examples/html/landingpage.html | 30 +- examples/src/landingpage.js | 48 +- index.html | 26 +- package.json | 2 +- src/index.ts | 5 +- 16 files changed, 330 insertions(+), 552 deletions(-) delete mode 100644 components/button/examples.iso.js rename components/button/{buttons.ts => floatingactionbutton.ts} (100%) delete mode 100644 components/button/test-button.mjs rename components/dropdown/{_dropdown.scss => ____dropdown.scss} (100%) delete mode 100644 components/dropdown/___dropdownSpec.js create mode 100644 components/dropdown/dropdown.css create mode 100644 components/dropdown/dropdown.mjs create mode 100644 components/dropdown/readme.md create mode 100644 examples/counter-app.iso.js diff --git a/components/button/examples.iso.js b/components/button/examples.iso.js deleted file mode 100644 index 5c7f3a4110..0000000000 --- a/components/button/examples.iso.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Number, Text } from '../atomic/atomic.mjs'; -import { Card } from '../card/card.mjs'; -import { Button } from './button.mjs'; - -// Example App (isomorphic javascript) - -function createCounterApp() { - return new Card({ - children: [ - new Text('Counter Example').setTagName('div'), - new Number(9), - new Button('➕'), - new Button('➖') - ] - }).addClassname('p-3'); -} - -export { createCounterApp }; diff --git a/components/button/buttons.ts b/components/button/floatingactionbutton.ts similarity index 100% rename from components/button/buttons.ts rename to components/button/floatingactionbutton.ts diff --git a/components/button/test-button.mjs b/components/button/test-button.mjs deleted file mode 100644 index 4f079113b7..0000000000 --- a/components/button/test-button.mjs +++ /dev/null @@ -1,16 +0,0 @@ -import { Number, Text } from '../atomic/atomic.mjs'; -import { Button, Card } from './button.mjs'; - -// Example App (isomorphic javascript) -const app = new Card({ - children: [ - new Text('Example App').setTagName('div'), // - new Number(9), - new Button('➕'), - new Button('➖') - ] -}).addClassname('p-3'); - -// Html -const html = app.toHTML(); -console.log(html); diff --git a/components/divider/divider.mjs b/components/divider/divider.mjs index 94ab98100d..dff8d7c4c0 100644 --- a/components/divider/divider.mjs +++ b/components/divider/divider.mjs @@ -4,6 +4,7 @@ class Divider extends Component { constructor(options) { super(options); this.addClassname('divider'); + this.setAttribute('role', 'separator'); } } diff --git a/components/dropdown/_dropdown.scss b/components/dropdown/____dropdown.scss similarity index 100% rename from components/dropdown/_dropdown.scss rename to components/dropdown/____dropdown.scss diff --git a/components/dropdown/___dropdownSpec.js b/components/dropdown/___dropdownSpec.js deleted file mode 100644 index f50defa6cb..0000000000 --- a/components/dropdown/___dropdownSpec.js +++ /dev/null @@ -1,108 +0,0 @@ -describe('Dropdown Plugin:', () => { - const fixture = ``; - - beforeEach(() => { - XloadHtml(fixture); - M.Dropdown.init(document.querySelectorAll('.dropdown-trigger'), { - inDuration: 0, - outDuration: 0 - }); - }); - afterEach(() => XunloadFixtures()); - - describe('Dropdown', () => { - let normalDropdown; - - it('should open and close programmatically', (done) => { - const dropdown1 = document.querySelector('#dropdown1'); - normalDropdown = document.querySelector('#dropdownActivator'); - expect(dropdown1).toBeHidden('Should be hidden before dropdown is opened.'); - M.Dropdown.getInstance(normalDropdown).open(); - //setTimeout(() => { - expect(dropdown1).toBeVisible('Should be shown after dropdown is opened.'); - M.Dropdown.getInstance(normalDropdown).close(); - setTimeout(() => { - expect(dropdown1).toBeHidden('Should be hidden after dropdown is closed.'); - done(); - }, 5); // 400 - //}, 400); - }); - - it('should close dropdown on document click if programmatically opened', (done) => { - const dropdown1 = document.querySelector('#dropdown1'); - normalDropdown = document.querySelector('#dropdownActivator'); - expect(dropdown1).toBeHidden('Should be hidden before dropdown is opened.'); - M.Dropdown.getInstance(normalDropdown).open(); - setTimeout(() => { - expect(dropdown1).toBeVisible('Should be shown after dropdown is opened.'); - click(document.body); - setTimeout(() => { - expect(dropdown1).toBeHidden('Should be hidden after dropdown is closed.'); - done(); - }, 5); // 400 - }, 5); // 400 - }); - - it('should bubble events correctly', (done) => { - const dropdown2 = document.querySelector('#dropdown2'); - normalDropdown = document.querySelector('#dropdownBubble'); - expect(dropdown2).toBeHidden('Should be hidden before dropdown is opened.'); - click(normalDropdown.querySelector('i')); - setTimeout(() => { - expect(dropdown2).toBeVisible('Should be shown after dropdown is opened.'); - click(document.body); - setTimeout(() => { - expect(dropdown2).toBeHidden('Should be hidden after dropdown is closed.'); - done(); - }, 5); // 400 - }, 5); // 400 - }); - - it('hovered should destroy itself', (done) => { - const dropdownTrigger = document.querySelector('#dropdownDestroyTrigger'); - M.Dropdown.getInstance(dropdownTrigger).destroy(); - M.Dropdown.init(dropdownTrigger, { hover: true }); - expect(() => { - M.Dropdown.getInstance(dropdownTrigger).destroy(); - }).not.toThrow(); - //setTimeout(() => { - done(); - //}, 400); - }); - }); -}); diff --git a/components/dropdown/dropdown.css b/components/dropdown/dropdown.css new file mode 100644 index 0000000000..576dbe5a22 --- /dev/null +++ b/components/dropdown/dropdown.css @@ -0,0 +1,60 @@ +/* Base styles for the popover element */ +.dropdown-content[popover] { + /* Reset default popover browser styles */ + margin: 0; + padding: 0.5rem 0; + border: 1px solid #ccc; + border-radius: 6px; + background-color: #fff; + list-style: none; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + + /* Automatic flip if top/bottom or left/right overflows viewport */ + position-try-fallbacks: flip-block, flip-inline; + + /* Smooth entry / exit transitions */ + opacity: 0; + transform: scale(0.95); + transition: + opacity 150ms ease, + transform 150ms ease, + display 150ms allow-discrete; +} + +/* Open State */ +.dropdown-content[popover]:popover-open { + opacity: 1; + transform: scale(1); +} + +/* Entry animation start point */ +@starting-style { + .dropdown-content[popover]:popover-open { + opacity: 0; + transform: scale(0.95); + } +} + +/* Styling dropdown items */ +.dropdown-content li { + padding: 0; +} + +.dropdown-content li a, +.dropdown-content li button { + display: block; + width: 100%; + padding: 0.5rem 1rem; + text-align: left; + background: none; + border: none; + color: #333; + text-decoration: none; + cursor: pointer; +} + +.dropdown-content li:focus-within, +.dropdown-content li.active { + background-color: #f0f0f0; + outline: none; +} diff --git a/components/dropdown/dropdown.mjs b/components/dropdown/dropdown.mjs new file mode 100644 index 0000000000..0d3f957262 --- /dev/null +++ b/components/dropdown/dropdown.mjs @@ -0,0 +1 @@ +// TODO: Builder diff --git a/components/dropdown/dropdown.ts b/components/dropdown/dropdown.ts index b40e82eb7a..6931b6171d 100644 --- a/components/dropdown/dropdown.ts +++ b/components/dropdown/dropdown.ts @@ -17,11 +17,6 @@ export interface DropdownOptions extends BaseOptions { * @default true */ constrainWidth: boolean; - /** - * Provide an element that will be the bounding container of the dropdown. - * @default null - */ - container: Element; /** * If false, the dropdown will show below the trigger. * @default true @@ -37,16 +32,6 @@ export interface DropdownOptions extends BaseOptions { * @default false */ hover: boolean; - /** - * The duration of the transition enter in milliseconds. - * @default 150 - */ - inDuration: number; - /** - * The duration of the transition out in milliseconds. - * @default 250 - */ - outDuration: number; /** * Function called when dropdown starts entering. * @default null @@ -78,12 +63,9 @@ const _defaults: DropdownOptions = { alignment: 'left', autoFocus: true, constrainWidth: true, - container: null, coverTrigger: true, closeOnClick: true, hover: false, - inDuration: 150, - outDuration: 250, onOpenStart: null, onOpenEnd: null, onCloseStart: null, @@ -99,9 +81,6 @@ export class Dropdown extends Component implements Openable { dropdownEl: HTMLElement; /** If the dropdown is open. */ isOpen: boolean; - /** If the dropdown content is scrollable. */ - isScrollable: boolean; - isTouchMoving: boolean; /** The index of the item focused. */ focusedIndex: number; filterQuery: string[]; @@ -121,14 +100,10 @@ export class Dropdown extends Component implements Openable { }; this.isOpen = false; - this.isScrollable = false; - this.isTouchMoving = false; this.focusedIndex = -1; this.filterQuery = []; - this.el.ariaExpanded = 'false'; - // Move dropdown-content after dropdown-trigger - this._moveDropdownToElement(); + this._setupPopoverAndAnchor(); this._makeDropdownFocusable(); this._setupEventHandlers(); } @@ -137,23 +112,8 @@ export class Dropdown extends Component implements Openable { return _defaults; } - /** - * Initializes instance of Dropdown. - * @param el HTML element. - * @param options Component options. - */ static init(el: HTMLElement, options?: Partial): Dropdown; - /** - * Initializes instances of Dropdown. - * @param els HTML elements. - * @param options Component options. - */ static init(els: InitElements, options?: Partial): Dropdown[]; - /** - * Initializes instances of Dropdown. - * @param els HTML elements. - * @param options Component options. - */ static init( els: HTMLElement | InitElements, options: Partial = {} @@ -166,23 +126,63 @@ export class Dropdown extends Component implements Openable { } destroy() { - this._resetDropdownStyles(); this._removeEventHandlers(); + if (this.dropdownEl?.hasAttribute('popover')) { + this.dropdownEl.removeAttribute('popover'); + } Dropdown._dropdowns.splice(Dropdown._dropdowns.indexOf(this), 1); this.el['M_Dropdown'] = undefined; } + /** + * Applies CSS Anchor Positioning and Popover attributes to the elements + */ + private _setupPopoverAndAnchor() { + if (!this.dropdownEl) return; + + // Set Popover API attributes + this.dropdownEl.popover = 'auto'; + + // Generate unique anchor name if necessary + const anchorName = `--dropdown-anchor-${this.id || Math.random().toString(36).substring(2, 9)}`; + + // Set CSS Anchor variables directly on elements + this.el.style.setProperty('anchor-name', anchorName); + this.dropdownEl.style.setProperty('position-anchor', anchorName); + + // Apply native anchor positioning via inline styles or class rules + this.dropdownEl.style.position = 'fixed'; + this.dropdownEl.style.margin = '0'; + + // Width constraint + if (this.options.constrainWidth) { + this.dropdownEl.style.width = 'anchor-size(width)'; + } + + // Vertical placement (Cover Trigger vs Below Trigger) + const topPosition = this.options.coverTrigger ? 'anchor(top)' : 'anchor(bottom)'; + this.dropdownEl.style.top = `position-area(${topPosition})`; + + // Horizontal alignment + if (this.options.alignment === 'right') { + this.dropdownEl.style.left = 'anchor(right)'; + this.dropdownEl.style.transform = 'translateX(-100%)'; + } else { + this.dropdownEl.style.left = 'anchor(left)'; + } + } + _setupEventHandlers() { - // Trigger keydown handler this.el.addEventListener('keydown', this._handleTriggerKeydown); - // Item click handler this.dropdownEl?.addEventListener('click', this._handleDropdownClick); - // Hover event handlers + + // Listen to native Popover Toggle events to manage lifecycle and state synchronization + this.dropdownEl?.addEventListener('beforetoggle', this._handlePopoverToggle); + if (this.options.hover) { this.el.addEventListener('mouseenter', this._handleMouseEnter); this.el.addEventListener('mouseleave', this._handleMouseLeave); this.dropdownEl.addEventListener('mouseleave', this._handleMouseLeave); - // Click event handlers } else { this.el.addEventListener('click', this._handleClick); } @@ -190,7 +190,9 @@ export class Dropdown extends Component implements Openable { _removeEventHandlers() { this.el.removeEventListener('keydown', this._handleTriggerKeydown); - this.dropdownEl.removeEventListener('click', this._handleDropdownClick); + this.dropdownEl?.removeEventListener('click', this._handleDropdownClick); + this.dropdownEl?.removeEventListener('beforetoggle', this._handlePopoverToggle); + if (this.options.hover) { this.el.removeEventListener('mouseenter', this._handleMouseEnter); this.el.removeEventListener('mouseleave', this._handleMouseLeave); @@ -200,23 +202,35 @@ export class Dropdown extends Component implements Openable { } } - _setupTemporaryEventHandlers() { - document.body.addEventListener('click', this._handleDocumentClick); - document.body.addEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.addEventListener('keydown', this._handleDropdownKeydown); - window.addEventListener('resize', this._handleWindowResize); - } + private _handlePopoverToggle = (e: ToggleEvent) => { + if (e.newState === 'open') { + this.isOpen = true; + this.el.setAttribute('aria-expanded', 'true'); + this.dropdownEl.addEventListener('keydown', this._handleDropdownKeydown); - _removeTemporaryEventHandlers() { - document.body.removeEventListener('click', this._handleDocumentClick); - document.body.removeEventListener('touchmove', this._handleDocumentTouchmove); - this.dropdownEl.removeEventListener('keydown', this._handleDropdownKeydown); - window.removeEventListener('resize', this._handleWindowResize); - } + if (typeof this.options.onOpenEnd === 'function') { + this.options.onOpenEnd.call(this, this.el); + } + if (this.options.autoFocus) { + this._focusFocusedItem(); + } + } else { + this.isOpen = false; + this.focusedIndex = -1; + this.el.setAttribute('aria-expanded', 'false'); + this.dropdownEl.removeEventListener('keydown', this._handleDropdownKeydown); + + if (typeof this.options.onCloseEnd === 'function') { + this.options.onCloseEnd.call(this, this.el); + } + if (this.options.autoFocus) { + this.el.focus(); + } + } + }; _handleClick = (e: MouseEvent) => { e.preventDefault(); - //this._moveDropdown((e.target).closest('li')); if (this.isOpen) { this.close(); } else { @@ -225,43 +239,24 @@ export class Dropdown extends Component implements Openable { }; _handleMouseEnter = () => { - //this._moveDropdown((e.target).closest('li')); this.open(); }; _handleMouseLeave = (e: MouseEvent) => { const toEl = e.relatedTarget as HTMLElement; + if (!toEl) return; + const leaveToDropdownContent = !!toEl.closest('.dropdown-content'); - let leaveToActiveDropdownTrigger = false; const closestTrigger = toEl.closest('.dropdown-trigger'); - if (closestTrigger && !!closestTrigger['M_Dropdown'] && closestTrigger['M_Dropdown'].isOpen) { - leaveToActiveDropdownTrigger = true; - } - // Close hover dropdown if mouse did not leave to either active dropdown-trigger or dropdown-content - if (!leaveToActiveDropdownTrigger && !leaveToDropdownContent) { - this.close(); - } - }; + const leaveToActiveDropdownTrigger = + closestTrigger && !!closestTrigger['M_Dropdown'] && closestTrigger['M_Dropdown'].isOpen; - _handleDocumentClick = (e: MouseEvent) => { - const target = e.target; - if (this.options.closeOnClick && target.closest('.dropdown-content') && !this.isTouchMoving) { - // isTouchMoving to check if scrolling on mobile. + if (!leaveToActiveDropdownTrigger && !leaveToDropdownContent) { this.close(); - } else if (!target.closest('.dropdown-content')) { - // Do this one frame later so that if the element clicked also triggers _handleClick - // For example, if a label for a select was clicked, that we don't close/open the dropdown - setTimeout(() => { - if (this.isOpen) { - this.close(); - } - }, 0); } - this.isTouchMoving = false; }; _handleTriggerKeydown = (e: KeyboardEvent) => { - // ARROW DOWN OR ENTER WHEN SELECT IS CLOSED - open Dropdown const arrowDownOrEnter = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ENTER.includes(e.key); if (arrowDownOrEnter && !this.isOpen) { @@ -270,36 +265,31 @@ export class Dropdown extends Component implements Openable { } }; - _handleDocumentTouchmove = (e: TouchEvent) => { - const target = e.target; - if (target.closest('.dropdown-content')) { - this.isTouchMoving = true; - } - }; - _handleDropdownClick = (e: MouseEvent) => { - // onItemClick callback - if (typeof this.options.onItemClick === 'function') { - const itemEl = (e.target).closest('li'); + const itemEl = (e.target).closest('li'); + if (typeof this.options.onItemClick === 'function' && itemEl) { this.options.onItemClick.call(this, itemEl); } + + if (this.options.closeOnClick) { + this.close(); + } }; _handleDropdownKeydown = (e: KeyboardEvent) => { const arrowUpOrDown = Utils.keys.ARROW_DOWN.includes(e.key) || Utils.keys.ARROW_UP.includes(e.key); + if (Utils.keys.TAB.includes(e.key)) { - e.preventDefault(); this.close(); - } - // Navigate down dropdown list - else if (arrowUpOrDown && this.isOpen) { + } else if (arrowUpOrDown && this.isOpen) { e.preventDefault(); const direction = Utils.keys.ARROW_DOWN.includes(e.key) ? 1 : -1; let newFocusedIndex = this.focusedIndex; let hasFoundNewIndex = false; + do { - newFocusedIndex = newFocusedIndex + direction; + newFocusedIndex += direction; if ( !!this.dropdownEl.children[newFocusedIndex] && (this.dropdownEl.children[newFocusedIndex]).tabIndex !== -1 @@ -310,34 +300,26 @@ export class Dropdown extends Component implements Openable { } while (newFocusedIndex < this.dropdownEl.children.length && newFocusedIndex >= 0); if (hasFoundNewIndex) { - // Remove active class from old element - if (this.focusedIndex >= 0) + if (this.focusedIndex >= 0) { this.dropdownEl.children[this.focusedIndex].classList.remove('active'); + } this.focusedIndex = newFocusedIndex; this._focusFocusedItem(); } - } - // ENTER selects choice on focused item - else if (Utils.keys.ENTER.includes(e.key) && this.isOpen) { - // Search for and + + +``` diff --git a/examples/counter-app.iso.js b/examples/counter-app.iso.js new file mode 100644 index 0000000000..0e468d4e65 --- /dev/null +++ b/examples/counter-app.iso.js @@ -0,0 +1,64 @@ +import { Number, Text } from '../components/atomic/atomic.mjs'; +import { Card } from '../components/card/card.mjs'; +import { Button } from '../components/button/button.mjs'; + +function createCounterApp() { + return new Card({ + children: [ + new Text('My Counter').setTagName('div'), + new Number(9), + new Button('➕'), + new Button('➖') + ] + }).addClassname('p-3'); +} + +//====== Client Side Logic + +function count(input) { + const value = input.value + input.increment; + return { value }; +} + +function hydrate(domElement, initState = { value: 12 }) { + const state = initState; + + const btns = domElement.querySelectorAll('.btn'); // input + const numberEl = domElement.querySelector('.mw-number'); // output + + numberEl.innerHTML = state.value; + + btns[0].addEventListener('click', (e) => { + state.value = count({ value: state.value, increment: 1 }).value; + numberEl.innerHTML = state.value; + }); + btns[1].addEventListener('click', (e) => { + state.value = count({ value: state.value, increment: -1 }).value; + numberEl.innerHTML = state.value; + }); +} + +class CounterApp extends HTMLElement { + constructor() { + super(); + this.count = 0; + } + + connectedCallback() { + // Da das Template via DSD geladen wurde, existiert shadowRoot bereits! + if (this.shadowRoot) { + this.btn = this.shadowRoot.querySelector('#btn'); + this.output = this.shadowRoot.querySelector('#output'); + + // Event-Listener hinzufügen + this.btn.addEventListener('click', () => this.increment()); + } + } + + increment() { + this.count++; + this.output.textContent = this.count; + } +} + +export { createCounterApp, hydrate, CounterApp }; diff --git a/examples/html/landingpage.html b/examples/html/landingpage.html index 11c7746f30..240e27305d 100644 --- a/examples/html/landingpage.html +++ b/examples/html/landingpage.html @@ -6,24 +6,44 @@ My Landingpage +
-

Landing Page

+

a

-
Hero Section
A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.
- You can also checkout the Blog
+ You can also checkout the Blog + klöxökkökökxl +
+ + + + +
Hello, this is my landing page!
- - + + diff --git a/examples/src/landingpage.js b/examples/src/landingpage.js index e287d503b5..d83134ee5b 100644 --- a/examples/src/landingpage.js +++ b/examples/src/landingpage.js @@ -2,24 +2,48 @@ import { Text } from '../../components/atomic/atomic.mjs'; import { Container, Page } from '../../components/atomic/page.mjs'; const landingPage = new Page({ - title: 'My Landingpage', - description: 'Introducing the new Phone', + title: 'T-Shirt Landingpage', + description: 'Introducing the new T-Shirt from Materialize', keywords: 'App launches, SaaS companies, small service businesses, and single-product e-commerce', children: [ - new Container({ children: new Text('Landing Page').setTagName('h1') }), - new Container(``), - new Container({ - children: 'Hero Section', - description: `A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),' + - 'feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.". - You can also checkout the Blog` - }), + new Container({ children: new Text('a').setTagName('h1') }), + //new Container(``), + new Container({ children: 'T-Shirt', description: `Nothing to see here` }), + // new Container(`A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.
- You can also checkout the Blog`), + You can also checkout the Blog + klöxökkökökxl +
+ + + + + `), + new Container('Hello, this is my landing page!').addClassname('pt-5') ] -}).addStyleUrl('/dist/css/materialize.css'); +}); +// CSS +landingPage + .addStyleUrl('/dist/css/materialize.css') + .addStyleUrl('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined'); +// Client JS +landingPage.addJavascriptUrl('/dist/js/materialize.js'); +landingPage.addJavascript(`M.AutoInit();`); const html = landingPage.toHTML(); console.log(html); diff --git a/index.html b/index.html index 9cf2563e1a..df5fd33439 100644 --- a/index.html +++ b/index.html @@ -148,38 +148,16 @@
Tabs
//------------------------------------- Example (Nested components to widget) - import { createCounterApp } from '/components/button/examples.iso.js'; + import { createCounterApp, hydrate } from './examples/counter-app.iso.js'; const app = createCounterApp(); const appHtml = app.toHTML(); - console.log(appHtml); - - // html => element const template = document.createElement('template'); template.innerHTML = appHtml; const appElem = template.content.firstElementChild; document.querySelector('.app').replaceChildren(appElem); + hydrate(appElem); - function count(input) { - const value = input.value + input.increment; - return { value } - } - - const state = { value: 12 }; - - const numberEl = appElem.querySelector('.mw-number'); // output - const btns = appElem.querySelectorAll('.btn'); // input - - numberEl.innerHTML = state.value; - - btns[0].addEventListener('click', e => { - state.value = count({ value: state.value , increment: 1 }).value; - numberEl.innerHTML = state.value; - }) - btns[1].addEventListener('click', e => { - state.value = count({ value: state.value , increment: -1 }).value; - numberEl.innerHTML = state.value; - }) `).join('\n')} ${this.#scripts.map((s) => ``).join('\n')} diff --git a/examples/html/blog.html b/examples/html/blog.html index 7ec934a27b..7a866f5280 100644 --- a/examples/html/blog.html +++ b/examples/html/blog.html @@ -15,8 +15,8 @@ -
-
+
+

Materialize Web Blog

@@ -46,9 +46,9 @@

Why Choose It for Your Next Project?

This is a test Landingpage. ok it can produce nested html too...
Or you can go to the Portfolio
Sidebar or navigation dropdowns ("Tech," "Lifestyle")
+
-
diff --git a/examples/html/landingpage.html b/examples/html/landingpage.html index 240e27305d..135ae854f0 100644 --- a/examples/html/landingpage.html +++ b/examples/html/landingpage.html @@ -4,18 +4,17 @@ - My Landingpage + T-Shirt Landingpage -
-
+

a

-
Hero Section
+
T-Shirt
A bold "Hero" section at the top with a clear headline, followed by social proof (reviews/logos),
feature blocks, and multiple Calls- to - Action(CTAs) like "Sign Up" or "Buy Now.
You can also checkout the Blog @@ -42,7 +41,6 @@

a

Hello, this is my landing page!
-
diff --git a/examples/html/portfolio.html b/examples/html/portfolio.html index d15f929609..532e795248 100644 --- a/examples/html/portfolio.html +++ b/examples/html/portfolio.html @@ -9,8 +9,7 @@ -
-
+

My Portfolio

@@ -18,7 +17,6 @@

My Portfolio

Sidebar
-
diff --git a/examples/src/blog.js b/examples/src/blog.js index ee3bcbcd10..0ad4eaf369 100644 --- a/examples/src/blog.js +++ b/examples/src/blog.js @@ -35,44 +35,52 @@ const blogPage = new Page({ title: 'Materialize Web Blog', description: 'This is a custom blog', keywords: 'News sites, personal journals, niche resource hubs, and content creators.', - children: [ - // TODO: use NavigationBar Component - new Container({ - children: new Text('Materialize Web Blog').setTagName('p').addClassname('py-3') - }).addClassname('wrapper-1'), + children: new Container({ + children: [ + // TODO: use NavigationBar Component + new Container({ + children: new Text('Materialize Web Blog').setTagName('p').addClassname('py-3') + }).addClassname('wrapper-1'), - new Container({ - children: [ - new AssistChip({ href: './landingpage.html', name: 'Visit Landingpage' }) - .addClassname('tooltipped') // tooltip - .setAttribute('data-tooltip', "I'm a toolip") - .setAttribute('data-position', 'bottom'), - new AssistChip({ href: './portfolio.html', name: 'Visit Porfolio' }) - ] - }) - .addClassname('g-2') - .addClassname('p-2') - .addClassname('secondary') - .addClassname('row'), + new Container({ + children: [ + new AssistChip({ href: './landingpage.html', name: 'Visit Landingpage' }) + .addClassname('tooltipped') // tooltip + .setAttribute('data-tooltip', "I'm a toolip") + .setAttribute('data-position', 'bottom'), + new AssistChip({ href: './portfolio.html', name: 'Visit Porfolio' }) + ] + }) + .addClassname('g-2') + .addClassname('p-2') + .addClassname('secondary') + .addClassname('row'), - new Breadcrumb() - .setCrumbs(['Home', 'Articles', 'Crafting Sleek, Responsive Interfaces with MaterializeWeb']) - .addClassname('py-5'), + new Breadcrumb() + .setCrumbs([ + 'Home', + 'Articles', + 'Crafting Sleek, Responsive Interfaces with MaterializeWeb' + ]) + .addClassname('py-5'), - myArticle, - new Container({ - children: - '2 or 3-column masonry grid showing article thumbnails, titles, and publication dates' - }).addClassname('py-5'), - new Button({ children: 'Call to action' }), - new Text( - `This is a test Landingpage. ok it can produce nested html too...
+ myArticle, + new Container({ + children: + '2 or 3-column masonry grid showing article thumbnails, titles, and publication dates' + }).addClassname('py-5'), + new Button({ children: 'Call to action' }), + new Text( + `This is a test Landingpage. ok it can produce nested html too...
Or you can go to the Portfolio` - ), - new Container({ - children: 'Sidebar or navigation dropdowns ("Tech," "Lifestyle")' - }).addClassname('py-5') - ] + ), + new Container({ + children: 'Sidebar or navigation dropdowns ("Tech," "Lifestyle")' + }).addClassname('py-5') + ] + }) + .setTagName('main') + .addClassname('container') }); // CSS blogPage From ea02aa12042c48cd21ac645c65cc9696a9abeb1c Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Mon, 17 Aug 2026 08:51:45 +0200 Subject: [PATCH 24/60] feat: add drawer --- components/appbar/appbar.mjs | 2 +- components/navigation-drawer/drawer.mjs | 32 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 components/navigation-drawer/drawer.mjs diff --git a/components/appbar/appbar.mjs b/components/appbar/appbar.mjs index 75feacd8ee..2b2a9386cd 100644 --- a/components/appbar/appbar.mjs +++ b/components/appbar/appbar.mjs @@ -1,6 +1,6 @@ import { Component } from '../atomic/component.mjs'; -// AppBar is the old *Navbar* +// AppBar is the old "Navbar" class AppBar extends Component { #title = ''; diff --git a/components/navigation-drawer/drawer.mjs b/components/navigation-drawer/drawer.mjs new file mode 100644 index 0000000000..1e3a05bffa --- /dev/null +++ b/components/navigation-drawer/drawer.mjs @@ -0,0 +1,32 @@ +import { Component } from '../atomic/component.mjs'; + +// Drawer = old Sidenav + +class Drawer extends Component { + #items; + + constructor(options) { + super(options); + this.#items = []; + this.setTagName('ul').addClassname('sidenav'); + this.setAttribute('id', 'slide-out'); + } + + addItem(item) { + this.#items = item; + return this; + } + + toHTML() { + const html = `
  • cloudFirst Link With Icon
  • +
  • Second Link
  • +
  • +
  • Subheader
  • +
  • Third Link With Waves
  • `; + // menu + this.setChildren(html); + return super.toHTML(); + } +} + +export { Drawer }; From 522a8e2d220756c24accf5f8ae3866840eb5b46f Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Mon, 17 Aug 2026 11:11:30 +0200 Subject: [PATCH 25/60] fix: drawer and appbar items --- components/appbar/appbar.mjs | 10 ++++++++++ components/navigation-drawer/drawer.mjs | 8 +++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/components/appbar/appbar.mjs b/components/appbar/appbar.mjs index 2b2a9386cd..353865dcc7 100644 --- a/components/appbar/appbar.mjs +++ b/components/appbar/appbar.mjs @@ -4,9 +4,11 @@ import { Component } from '../atomic/component.mjs'; class AppBar extends Component { #title = ''; + #items; constructor(options) { super(options); + this.#items = []; this.setTagName('nav').addClassname('nav navbar'); } @@ -31,15 +33,23 @@ class AppBar extends Component { return this; } + addItem(item) { + this.#items.push(item); + return this; + } + toHTML() { const html = ``; beforeEach(() => { // Inject fixture HTML directly into the DOM diff --git a/components/chip/chips.ts b/components/chip/chips.ts index 94697dd176..f045cc7f5e 100644 --- a/components/chip/chips.ts +++ b/components/chip/chips.ts @@ -1,5 +1,5 @@ import { Utils } from '../../src/utils'; -import { Autocomplete, AutocompleteOptions } from '../search/autocomplete'; +import { Autocomplete, AutocompleteOptions } from '../autocomplete/autocomplete'; import { Component, BaseOptions, InitElements, MElement } from '../../src/component'; interface ChipData { diff --git a/components/datepicker/datepicker.ts b/components/datepicker/datepicker.ts index 7e2252c96d..0222cba2ef 100644 --- a/components/datepicker/datepicker.ts +++ b/components/datepicker/datepicker.ts @@ -4,7 +4,7 @@ import { FormSelect } from '../textfield/select'; import { DockedDisplayPlugin } from '../../src/dockedDisplayPlugin'; import { ModalDisplayPlugin } from '../../src/modalDisplayPlugin'; -export interface DateI18nOptions extends I18nOptions { +interface DateI18nOptions extends I18nOptions { previousMonth: string; nextMonth: string; months: string[]; @@ -14,7 +14,7 @@ export interface DateI18nOptions extends I18nOptions { weekdaysAbbrev: string[]; } -export interface DatepickerOptions extends BaseOptions { +interface DatepickerOptions extends BaseOptions { /** * The date output format for the input field value * or a function taking the date and outputting the @@ -297,7 +297,7 @@ const _defaults: DatepickerOptions = { onCancel: null }; -export class Datepicker extends Component { +class Datepicker extends Component { declare el: HTMLInputElement; id: string; multiple: boolean = false; @@ -1448,3 +1448,5 @@ export class Datepicker extends Component {
    `; } } + +export { DateI18nOptions, DatepickerOptions, Datepicker }; diff --git a/components/dropdown/dropdown.ts b/components/dropdown/dropdown.ts index 6931b6171d..12b294161e 100644 --- a/components/dropdown/dropdown.ts +++ b/components/dropdown/dropdown.ts @@ -1,7 +1,7 @@ import { Utils } from '../../src/utils'; import { Component, BaseOptions, InitElements, MElement, Openable } from '../../src/component'; -export interface DropdownOptions extends BaseOptions { +interface DropdownOptions extends BaseOptions { /** * Defines the edge the menu is aligned to. * @default 'left' @@ -73,7 +73,7 @@ const _defaults: DropdownOptions = { onItemClick: null }; -export class Dropdown extends Component implements Openable { +class Dropdown extends Component implements Openable { static _dropdowns: Dropdown[] = []; /** ID of the dropdown element. */ id: string; @@ -398,3 +398,5 @@ export class Dropdown extends Component implements Openable { // No-op required; browser layout engine handles anchor positioning. }; } + +export { DropdownOptions, Dropdown }; diff --git a/components/search/___autocompleteSpec.js b/components/search/___autocompleteSpec.js deleted file mode 100644 index 6be1d109c0..0000000000 --- a/components/search/___autocompleteSpec.js +++ /dev/null @@ -1,321 +0,0 @@ -describe('Autocomplete Plugin', () => { - const fixture = `
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    `; - - beforeEach(() => { - XloadHtml(fixture); - M.Autocomplete.init(document.querySelectorAll('input.autocomplete'), { - dropdownOptions: { - inDuration: 0, - outDuration: 0 - }, - data: [ - { id: 12, text: 'Apple' }, - { id: 13, text: 'Microsoft' }, - { - id: 42, - text: 'Google', - image: - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' - } - ] - }); - }); - afterEach(() => XunloadFixtures()); - - describe('Autocomplete', () => { - function resetAutocomplete(autocompleteElement, data) { - M.Autocomplete.getInstance(autocompleteElement).destroy(); - return M.Autocomplete.init(autocompleteElement, { - data: data, - minLength: 0, - dropdownOptions: { - inDuration: 0, - outDuration: 0 - } - }); - } - - function openDropdownAndSelectFirstOption(autocomplete, onFinish) { - click(autocomplete); - keyup(autocomplete, 9); // works - setTimeout(() => { - const firstOption = autocomplete.parentNode.querySelector('.autocomplete-content li'); - click(firstOption); - setTimeout(() => onFinish(), 10); - }, 10); // error caused by setTimeout in autocomplete component - } - - it('should work with multiple initializations', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - M.Autocomplete.init(normal, { hi: null }); - M.Autocomplete.init(normal, { hi: null }); - M.Autocomplete.init(normal, { hi: null }); - M.Autocomplete.init(normal, { - data: [ - { id: 12, text: 'Apple' }, - { id: 13, text: 'Microsoft' }, - { - id: 42, - text: 'Google', - image: - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' - } - ] - }); - const autocompleteEl = normal.parentNode.querySelectorAll('.autocomplete-content'); - expect(autocompleteEl.length).toEqual( - 1, - 'Should dynamically generate autocomplete structure.' - ); - done(); - }); - - it('should limit results in search function', (done) => { - const limited = document.querySelector('#limited-autocomplete'); - const data = []; - for (let i = 100; i >= 0; i--) { - const randString = 'a' + Math.random().toString(36).substring(2); - data.push({ id: randString }); - } - const limitedInstance = M.Autocomplete.getInstance(limited); - const limit = 20; - limitedInstance.options.onSearch = () => { - const filteredItems = data.slice(0, limit); - limitedInstance.setMenuItems(filteredItems); - }; - focus(limited); - limited.value = 'a'; - keyup(limited, 65); - setTimeout(() => { - const autocompleteEl = limitedInstance.container; - expect(autocompleteEl.children.length).toEqual( - 20, - 'Results should be at max the set limit' - ); - done(); - }, 10); - }); - - it('should open correctly from typing', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - const autocompleteEl = normal.parentNode.querySelector('.autocomplete-content'); - focus(normal); - normal.value = 'e'; - keyup(normal, 69); - setTimeout(() => { - expect(autocompleteEl.children.length).toEqual( - 2, - 'Results should show dropdown on text input' - ); - done(); - }, 10); - }); - - it('should open correctly from keyboard focus', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - const autocompleteEl = normal.parentNode.querySelector('.autocomplete-content'); - normal.value = 'e'; - keyup(normal, 9); - focus(normal); - setTimeout(() => { - expect(autocompleteEl.children.length).toEqual( - 2, - 'Results should show dropdown on text input' - ); - done(); - }, 10); - }); - - it('should select option on click', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - M.Autocomplete.init(normal, { - data: [{ id: 'Value A' }], - minLength: 0, - dropdownOptions: { - inDuration: 0, - outDuration: 0 - } - }); - openDropdownAndSelectFirstOption(normal, () => { - expect(normal.value).toEqual('Value A', 'Value should equal chosen option.'); - done(); - }); - }); - - it('should select proper options on both autocompletes', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - const limited = document.querySelector('#limited-autocomplete'); - M.Autocomplete.init(normal, { - data: [{ id: 'Value A' }], - minLength: 0, - dropdownOptions: { - inDuration: 0, - outDuration: 0 - } - }); - M.Autocomplete.init(limited, { - data: [{ id: 'Value B' }], - minLength: 0, - dropdownOptions: { - inDuration: 0, - outDuration: 0 - } - }); - openDropdownAndSelectFirstOption(normal, () => { - openDropdownAndSelectFirstOption(limited, () => { - expect(normal.value).toEqual('Value A', 'Value should equal chosen option.'); - expect(limited.value).toEqual('Value B', 'Value should equal chosen option.'); - done(); - }); - }); - }); - - it('destroy method should properly dispose autocomplete component', () => { - const normal = document.querySelector('#normal-autocomplete'); - const limited = document.querySelector('#limited-autocomplete'); - expect(normal.parentNode.querySelector('.autocomplete-content')).not.toBeNull(); - expect(limited.parentNode.querySelector('.autocomplete-content')).not.toBeNull(); - const normalInstance = M.Autocomplete.getInstance(normal); - const limitedInstance = M.Autocomplete.getInstance(limited); - normalInstance.destroy(); - limitedInstance.destroy(); - expect(normal.parentNode.querySelector('.autocomplete-content')).toBeNull(); - expect(limited.parentNode.querySelector('.autocomplete-content')).toBeNull(); - }); - - it('selectOption method should chose only from showed dropdown', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - const autocompleteInstance = resetAutocomplete(normal, [ - { id: 'Value Q1' }, - { id: 'Value Q' }, - { id: 'Value R' } - ]); - const autocompleteEl = normal.parentNode.querySelector('.autocomplete-content'); - - focus(normal); - normal.value = 'Q'; - keyup(normal, 81); - - setTimeout(() => { - expect(autocompleteEl.children.length).toBe(2); - const dropdownAutocompleteIds = Array.from(autocompleteEl.querySelectorAll('li')).map( - (liElement) => liElement.getAttribute('data-id') - ); - expect(dropdownAutocompleteIds).toEqual(['Value Q1', 'Value Q']); - - autocompleteInstance.selectOption('Value R'); - expect(normal.value) - .withContext('Only options from dropdown can be selected through selectOption') - .toBe('Q'); - autocompleteInstance.selectOption('Value Q'); - expect(normal.value) - .withContext('Only options from dropdown can be selected through selectOption') - .toBe('Value Q'); - done(); - }, 10); - }); - - it('setValues method should chose from any init data entry', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - const autocompleteInstance = resetAutocomplete(normal, [ - { id: 'Value Q1' }, - { id: 'Value Q' }, - { id: 'Value R' } - ]); - const autocompleteEl = normal.parentNode.querySelector('.autocomplete-content'); - - focus(normal); - normal.value = 'Q'; - keyup(normal, 81); - - setTimeout(function () { - expect(autocompleteEl.children.length).toBe(2); - const dropdownAutocompleteIds = Array.from(autocompleteEl.querySelectorAll('li')).map( - (liElement) => liElement.getAttribute('data-id') - ); - expect(dropdownAutocompleteIds).toEqual(['Value Q1', 'Value Q']); - - autocompleteInstance.setValues([{ id: 'Value R' }]); - expect(normal.value) - .withContext('Any option from init data can be selected through setValues') - .toBe('Value R'); - autocompleteInstance.setValues([{ id: 'Value Q' }]); - expect(normal.value) - .withContext('Any option from init data can be selected through setValues') - .toBe('Value Q'); - done(); - }, 10); - }); - - it('selected options should preselect option in single select', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - M.Autocomplete.getInstance(normal).destroy(); - M.Autocomplete.init(normal, { - data: [{ id: 'Value A', text: 'Text 1' }, { id: 'Value B', text: 'Text 2' }], - selected: ['Value B'], - }); - - setTimeout(() => { - expect(normal.value) - .withContext('Value should equal chosen option.') - .toBe('Text 2'); - done(); - }, 10); - }); - - it('selected options should preselect options in multi select', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - M.Autocomplete.getInstance(normal).destroy(); - M.Autocomplete.init(normal, { - data: [{ id: 'Value A', text: 'Text 1' }, { id: 'Value B', text: 'Text 2' }, { id: 'Value C', text: 'Text 3' }], - selected: ['Value A', 'Value B'] - }); - const instance = M.Autocomplete.getInstance(normal); - - setTimeout(() => { - const dropdownAutocompleteIds = Array.from(instance.selectedValues).map( - (selectedValue) => selectedValue.id - ); - expect(dropdownAutocompleteIds) - .withContext('Value should equal chosen option.') - .toEqual(['Value A', 'Value B']); - done(); - }, 10); - }); - - it('selectOptions should select multiple options', (done) => { - const normal = document.querySelector('#normal-autocomplete'); - resetAutocomplete(normal, [ - { id: 1, text: 'Value A' }, - { id: 2, text: 'Value B' }, - { id: 3, text: 'Value C' } - ]); - const selectOptions = [2, 3]; - const autocomplete = M.Autocomplete.getInstance(normal) - autocomplete.selectOptions(selectOptions); - setTimeout(() => { - expect(autocomplete.selectedValues.filter((value) => !(selectOptions.indexOf(value.id) === -1)).length === selectOptions.length) - .withContext('filtered selectValues based on selectOptions should match') - .toBe(true); - done(); - }, 10) - }); - }); -}); diff --git a/components/slider/range.ts b/components/slider/range.ts index 5a79c01e7d..61d758d88c 100644 --- a/components/slider/range.ts +++ b/components/slider/range.ts @@ -1,13 +1,11 @@ import { Component, BaseOptions, InitElements, MElement } from '../../src/component'; // eslint-disable-next-line @typescript-eslint/no-empty-object-type -export interface RangeOptions extends BaseOptions {} +interface RangeOptions extends BaseOptions {} const _defaults: RangeOptions = {}; -// TODO: !!!!! - -export class Range extends Component { +class Range extends Component { declare el: HTMLInputElement; private _mousedown: boolean; value: HTMLElement; @@ -214,3 +212,5 @@ export class Range extends Component { ); } } + +export { RangeOptions, Range }; diff --git a/components/textfield/___formsSpec.js b/components/textfield/___formsSpec.js deleted file mode 100644 index 0329cec516..0000000000 --- a/components/textfield/___formsSpec.js +++ /dev/null @@ -1,142 +0,0 @@ -const MULTILINE_TEXT = - 'This is line 1.\nThis is line 2.\nThis is line 3.\nThis is line 4.\nThis is line 5.\nAnd this is line 6.'; - -describe('Forms:', () => { - const fixture = `
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -`; - - beforeEach(() => { - XloadHtml(fixture); - M.CharacterCounter.init(document.querySelector('#character-counter')); - const inputs = document.querySelectorAll('input'); - inputs.forEach((input) => { - //input.dispatchEvent(new Event('focus')); - focus(input); - //input.focus(); - //input.blur(); - }); - }); - afterEach(() => XunloadFixtures()); - - describe('CharacterCounter', () => { - it('Should initialize', () => { - const el = document.querySelector('#character-counter'); - expect(() => M.CharacterCounter.getInstance(el)).not.toThrow(); - expect(M.CharacterCounter.getInstance(el)).toBeTruthy(); - }); - - it('Should exhibit counter', () => { - const counter = document.querySelector('#character-counter ~ .character-counter'); - expect(counter.textContent).toBe('0/10'); - }); - }); - - describe('TextArea Resize', () => { - it('Should resize', () => { - const el = document.querySelector('#textarea'); - const pHeight = el.clientHeight; - el.value = ` - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin eleifend urna orci, vitae sagittis ligula maximus quis. Duis eleifend ipsum vitae facilisis tincidunt. Aliquam condimentum consequat ex, ut commodo purus tristique at. Donec malesuada fringilla libero vel sodales. Nulla finibus volutpat lectus a varius. Praesent consequat ornare pulvinar. Quisque nec massa diam. - Nunc commodo tempus suscipit. Phasellus iaculis at lorem sit amet venenatis. Curabitur quis felis elementum enim fermentum dapibus. In pretium finibus mollis. Nam aliquet tristique diam sit amet ullamcorper. Suspendisse interdum, est sed aliquam dignissim, dolor augue tristique dui, non luctus felis dolor a dui. Suspendisse lacinia lorem nec enim ultricies maximus. Aenean quam erat, finibus non aliquam nec, pharetra vel metus. Nulla dignissim maximus cursus. - Integer massa est, semper eget sem quis, bibendum scelerisque odio. Nam sit amet urna auctor, luctus odio in, semper dui. Sed ut gravida libero, ac consectetur sem. Etiam pharetra pulvinar leo, eget imperdiet purus faucibus in. Cras blandit mi ullamcorper nulla viverra posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec pretium euismod tortor a lacinia. Vivamus ultrices vulputate purus et blandit. Fusce mi quam, consequat vitae pretium sed, tempus at ligula. - Suspendisse sodales et dolor vitae sollicitudin. Curabitur sed vestibulum sapien. Integer porttitor pulvinar ullamcorper. Sed ultrices varius augue, at bibendum magna congue sit amet. Nam enim purus, fermentum sed feugiat viverra, accumsan nec diam. Donec a auctor est. Aenean non ante metus. Pellentesque ante ligula, varius vel dignissim in, euismod vel diam. Donec est ante, rhoncus at eros sed, cursus pulvinar enim. In pellentesque, erat eu egestas tempor, ipsum turpis ornare dui, sed fringilla sem lorem in ligula. - Integer facilisis arcu eu posuere placerat. Nam vel leo magna. Proin mattis feugiat nisi, quis tincidunt magna pulvinar tincidunt. Aliquam eget nunc sapien. Maecenas vitae orci nunc. Nulla condimentum sapien quis sapien varius suscipit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non finibus nisl, et venenatis massa. - `.trim(); - M.Forms.textareaAutoResize(el); - expect(el.clientHeight).toBeGreaterThan(pHeight); - }); - - it('Programmatically initialized textarea resize', (done) => { - const element = document.querySelector('#textarea'); - M.Forms.InitTextarea(element); - const textareaHeight = element.clientHeight; - element.value = MULTILINE_TEXT; - keydown(element, 13); - setTimeout(() => { - expect(element.clientHeight).toBeGreaterThan(textareaHeight); - done(); - }, 10); - }); - - it('Automatically initialized textarea resize', (done) => { - const event = new Event('DOMContentLoaded'); - document.dispatchEvent(event); - const element = document.querySelector('#textarea'); - const textareaHeight = element.clientHeight; - element.value = MULTILINE_TEXT; - keydown(element, 13); - setTimeout(() => { - expect(element.clientHeight).toBeGreaterThan(textareaHeight); - done(); - }, 10); - }); - }); - - // No active class added, because it is now a css feature only - /* - it("should keep label active while focusing on input", () => { - inputs.forEach(input => { - expect(input.labels[0]).not.toHaveClass('active') - input.focus() - expect(input.labels[0]).toHaveClass('active') - input.blur() - expect(input.labels[0]).not.toHaveClass('active') - }) - }); - */ -}); diff --git a/package-lock.json b/package-lock.json index af00712f5a..8709d35fc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1300,9 +1300,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", - "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.5.tgz", + "integrity": "sha512-jfkGfTwhQpsiSckPF8r9bU3pn3vyd72NlWaO+TgEO6WPSDnUhXzrNYCHBMOYj0ACaUgjm6eERLF+XV9a6RstoA==", "cpu": [ "arm" ], @@ -1314,9 +1314,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", - "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.5.tgz", + "integrity": "sha512-oGVqyQlxnrz9/ty89oHpU857VUHEl5/Xu4R2lS+aivCTrNnSsbiENzTnNaBsjxH0CNWGPhzHArOLFwo+oKXveA==", "cpu": [ "arm64" ], @@ -1328,9 +1328,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", - "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.5.tgz", + "integrity": "sha512-bW7B8xMEq8n99Q3ieEcPRGuphurdZAaFzQc9Efyyw3FL6DZO6pMy9xhdN+kBoD7Sy05xNXSr4OyPPnpkYriS/A==", "cpu": [ "arm64" ], @@ -1342,9 +1342,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", - "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.5.tgz", + "integrity": "sha512-YSwBS86QeHOGlrxJ1PSOIZSkzRL/JmKeunhc+lV6M1a6En8QuVCD/T/qIA0J4Gd2Y86RIOBYrLcOUtqGh9+/1w==", "cpu": [ "x64" ], @@ -1356,9 +1356,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", - "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.5.tgz", + "integrity": "sha512-2fST8lILgl7cKbme/1KDdPCmbXbG+gqoV3bHp19L0ypX/3akYMBVdOunPleRCwonoLnXOZ/0F+Mt/v8POFmfcQ==", "cpu": [ "arm64" ], @@ -1370,9 +1370,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", - "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.5.tgz", + "integrity": "sha512-cpIxQCP9J+EVad0a6LO1kY3ZGODlk80VlI+2I96B8xMcdHZ4pLVhfQ49JFpYqjPF91FFkQWftf57YlDcTiw9yQ==", "cpu": [ "x64" ], @@ -1384,9 +1384,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", - "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.5.tgz", + "integrity": "sha512-r9fGh3eFs3e/udWh5ZjXQtxiYK/xoFxQaYR/cELxac/Udkl5Th+IsFm0CX3Kl9hmUH/we7EoMpjJgeQNnE0+IA==", "cpu": [ "arm" ], @@ -1401,9 +1401,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", - "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.5.tgz", + "integrity": "sha512-xdvFdp7OM6KLJviJT2g/YuRSUjnZgGHk4RNgwIbN7X6cPugOucV60DdHXWzsBVCUdrGb6qSXnJQrrAKMmQuj3Q==", "cpu": [ "arm" ], @@ -1418,9 +1418,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", - "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.5.tgz", + "integrity": "sha512-rRqILAndyzHzP7T9NFQrq+4HFWNhqkqkKur7eiBpfLmz01PO0JKx5Vchu3YllE4YXI/Ftgq/szrDWg5GJ0mI8g==", "cpu": [ "arm64" ], @@ -1435,9 +1435,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", - "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.5.tgz", + "integrity": "sha512-Gf4X3qVMucayUvux6aXXPgXovocSFUC0rrffDuPI/S2nHhNMhjcZxsrAFYCOF350PRreW1XwzFj3CT/3bKsWCw==", "cpu": [ "arm64" ], @@ -1452,9 +1452,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", - "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.5.tgz", + "integrity": "sha512-+s5qA0TNM0qm8PK/a5gt/1Hpx+NV08uSuCncvhziIlQzT6AEV2fnUQo7eBtFTFO0nA9scauvoR2HusfXmQnO4w==", "cpu": [ "loong64" ], @@ -1469,9 +1469,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", - "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.5.tgz", + "integrity": "sha512-ybb6QvWwWJCbBWqERpc8K3pYVGIrXlG8MEQ8IIuJY6Y9KdHQxoFoNyfkAOtKn1VHu3KuLidXvwrvGR1mEjeWCw==", "cpu": [ "loong64" ], @@ -1486,9 +1486,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", - "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.5.tgz", + "integrity": "sha512-nZb1DtnOyhCmYvsC8A2CwOkopVg+IS1+fPUa7rMOAXtNw5+lLCLLPqd6XAiNrGtoQKsbvIBOwsHnBH/3wnb4HQ==", "cpu": [ "ppc64" ], @@ -1503,9 +1503,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", - "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.5.tgz", + "integrity": "sha512-yMbj63Sp89ryrXLWyz+sy+fYD2HpOnMCLGbe4Oa1smclFSUukdtD/BgdiHaAetJNb74URD8U4hM+qG5KVzMEkg==", "cpu": [ "ppc64" ], @@ -1520,9 +1520,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", - "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.5.tgz", + "integrity": "sha512-mhoan3OJw2kYV/e1jtIdmvUZgyBFeA6zGWsOswmR0Tg19TQbowZuR+JMLID6spbbBN7Zee2ejrgmy3+FxGrIdA==", "cpu": [ "riscv64" ], @@ -1537,9 +1537,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", - "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.5.tgz", + "integrity": "sha512-5ZTLmjWbb1VZdjuyhe83K/8QO0/h11midQCBP+X5OYn32ra7eOBoM0ZqtaY4nkgNsYgmdVhMYPoyVPTjUpHf3w==", "cpu": [ "riscv64" ], @@ -1554,9 +1554,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", - "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.5.tgz", + "integrity": "sha512-m53kG+br6PGxOTmgBEM2DHSDs9RVjsyEbUwjJPJGTFm1grWOG8EKJggDCTb60unD4Tjby8fi7/m9XfkEWasVWg==", "cpu": [ "s390x" ], @@ -1571,9 +1571,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", - "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.5.tgz", + "integrity": "sha512-6RHPJR1g/uvdYU8uXBnfq3nlqyZCP82Fr6NHgfGoaIeSh0YEqnX/x6uA9MmJJbnSH7swqX4F+CkGdUF+6doiQA==", "cpu": [ "x64" ], @@ -1588,9 +1588,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", - "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.5.tgz", + "integrity": "sha512-xs+OXQtEXgpXT0DmA5+U3qnRZHdCST/5HRQxS8wSPZTUZN/EMWeHuSIod32LQklTBZBV9DyfncKBQ8n5V3eFdw==", "cpu": [ "x64" ], @@ -1605,9 +1605,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", - "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.5.tgz", + "integrity": "sha512-e7hD+sl3s+mcLQDZ8pbudBVsdG6r5yN4w3LqG2TJ8sQHDpblWj5lrJs/3m01Cvlxbt4x13zu5thLjgypgtkYzw==", "cpu": [ "x64" ], @@ -1619,9 +1619,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", - "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.5.tgz", + "integrity": "sha512-GiyJaCf+WpMub/17aPcKk27QMl5W6f+KhdPTjlFOn5akH5Wa/DCM9Stdx5cDfmasyKB08MqpVQ1uJE2RkkpbXg==", "cpu": [ "arm64" ], @@ -1633,9 +1633,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", - "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.5.tgz", + "integrity": "sha512-+OQ8U2DdoEfXl8T4Fb18AjmEwbXMerKDKCL8yCPAYhKCEEKoul7rkbeGCBFCbAlaGaa7pmtRTpkAJM2LE/i5FA==", "cpu": [ "arm64" ], @@ -1647,9 +1647,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", - "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.5.tgz", + "integrity": "sha512-KanvAZrPKbDBFwrgiU9yEVpQoox9QPV1WZOXX7HudJQY+eSlu82CtWxDU8WtuRRvtN5EGkLczkd6Y6DTcvm9wA==", "cpu": [ "ia32" ], @@ -1661,9 +1661,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", - "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.5.tgz", + "integrity": "sha512-1aC3UEWTtRl3RK3VpDJ/Tqk1XI4SLTmXIthAq6wRWo8XiSXJNd+VprJM4/1P4+i6HIaFEFlVi9sTTziniD2tOQ==", "cpu": [ "x64" ], @@ -1675,9 +1675,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", - "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.5.tgz", + "integrity": "sha512-/gDJaRs4gl0NPIwqCz+6PkpmhhjRAD2j6P4rSNHBzUkO3naEx2mIU0pRle1vUNRQ7mE/+8OOeXLTv/J56FKiQg==", "cpu": [ "x64" ], @@ -1934,9 +1934,9 @@ "license": "MIT" }, "node_modules/@testing-library/user-event": { - "version": "14.6.4", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.4.tgz", - "integrity": "sha512-QCGwP6QrjypBLwyj5cuyfVamkaIEy/XGY+1VDehbtbQqOggYmTFpFOdWR5mPz14vX8vXLMVjDHlRNBcClyO9ew==", + "version": "14.6.6", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.6.tgz", + "integrity": "sha512-Jbs9FpkkIDw8FgSc6kOVsOv8JuuqGAL7J4X1oot77JxAoDlkNn2GRkd0aYRVuQ+pVQAiHWVkE4rX/dkF5fBiCw==", "dev": true, "license": "MIT", "engines": { @@ -2410,13 +2410,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", - "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", + "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.10", + "@vitest/utils": "4.1.11", "pathe": "^2.0.3" }, "funding": { @@ -2424,9 +2424,9 @@ } }, "node_modules/@vitest/runner/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", "dev": true, "license": "MIT", "dependencies": { @@ -2437,13 +2437,13 @@ } }, "node_modules/@vitest/runner/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", + "@vitest/pretty-format": "4.1.11", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2462,14 +2462,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", - "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", + "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/pretty-format": "4.1.11", + "@vitest/utils": "4.1.11", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -2478,9 +2478,9 @@ } }, "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", "dev": true, "license": "MIT", "dependencies": { @@ -2491,13 +2491,13 @@ } }, "node_modules/@vitest/snapshot/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", + "@vitest/pretty-format": "4.1.11", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2883,9 +2883,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.11.13", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz", - "integrity": "sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==", + "version": "2.11.17", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.17.tgz", + "integrity": "sha512-KAUDn1OSS0fmPlGO+NOUMRcOQ/b/shUBH3OgkG73mPgdf+JD/BQ6fHboGxNOxnUmlwcq+lLq3dTkayRPuSfXwg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3336,9 +3336,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.405", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.405.tgz", - "integrity": "sha512-bNglH7lPH5l+yHOes7Zr4VqxhOy4BQ9ZBUX4VdoFgxMpzJk7W1ZoO3Vgd9Pxa9PyjQ76sfm2aKH/nzEcCNRlew==", + "version": "1.5.412", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.412.tgz", + "integrity": "sha512-z4rMe3esBzlzovKHj4gxJnsCGZRK5l4baUvm+gCGJBPE+gsyUMKsuU9tnEUtI1dOebXz1ytAPGjvXhmQ7rIPwA==", "dev": true, "license": "ISC" }, @@ -3373,9 +3373,9 @@ } }, "node_modules/es-module-lexer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", - "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", "dev": true, "license": "MIT" }, @@ -3461,6 +3461,7 @@ "version": "9.39.5", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { @@ -4041,9 +4042,9 @@ "license": "ISC" }, "node_modules/happy-dom": { - "version": "20.11.2", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.11.2.tgz", - "integrity": "sha512-7MB+bJLkxu3SowAfBJbjW+c55kNz5tkR45gu2qzrxznezhLeN5YIlJbwUgSzlGc+qWoZ8Ykg71H5ezz69xixrw==", + "version": "20.11.6", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.11.6.tgz", + "integrity": "sha512-Hldbg8AdAa5a5oDcZpjqnGitp7JB0hqWmfv/8qr+kft4vzSD8BHsbdRfzYvL/0QcbKcURC/yyoygbeDQarPvYg==", "dev": true, "license": "MIT", "dependencies": { @@ -5158,9 +5159,9 @@ } }, "node_modules/rollup": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", - "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "version": "4.62.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.5.tgz", + "integrity": "sha512-/tqMfgP7GPA3PHhCmuiS4vIjrSVhHLgY++i+dhbG462euyAj7FpM4D9uq1X3BgjlqRdpcOrYhcQtfiQLNc8tqw==", "dev": true, "license": "MIT", "dependencies": { @@ -5175,31 +5176,31 @@ }, "optionalDependencies": { "@napi-rs/lzma-linux-x64-gnu": "1.5.1", - "@rollup/rollup-android-arm-eabi": "4.62.4", - "@rollup/rollup-android-arm64": "4.62.4", - "@rollup/rollup-darwin-arm64": "4.62.4", - "@rollup/rollup-darwin-x64": "4.62.4", - "@rollup/rollup-freebsd-arm64": "4.62.4", - "@rollup/rollup-freebsd-x64": "4.62.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", - "@rollup/rollup-linux-arm-musleabihf": "4.62.4", - "@rollup/rollup-linux-arm64-gnu": "4.62.4", - "@rollup/rollup-linux-arm64-musl": "4.62.4", - "@rollup/rollup-linux-loong64-gnu": "4.62.4", - "@rollup/rollup-linux-loong64-musl": "4.62.4", - "@rollup/rollup-linux-ppc64-gnu": "4.62.4", - "@rollup/rollup-linux-ppc64-musl": "4.62.4", - "@rollup/rollup-linux-riscv64-gnu": "4.62.4", - "@rollup/rollup-linux-riscv64-musl": "4.62.4", - "@rollup/rollup-linux-s390x-gnu": "4.62.4", - "@rollup/rollup-linux-x64-gnu": "4.62.4", - "@rollup/rollup-linux-x64-musl": "4.62.4", - "@rollup/rollup-openbsd-x64": "4.62.4", - "@rollup/rollup-openharmony-arm64": "4.62.4", - "@rollup/rollup-win32-arm64-msvc": "4.62.4", - "@rollup/rollup-win32-ia32-msvc": "4.62.4", - "@rollup/rollup-win32-x64-gnu": "4.62.4", - "@rollup/rollup-win32-x64-msvc": "4.62.4", + "@rollup/rollup-android-arm-eabi": "4.62.5", + "@rollup/rollup-android-arm64": "4.62.5", + "@rollup/rollup-darwin-arm64": "4.62.5", + "@rollup/rollup-darwin-x64": "4.62.5", + "@rollup/rollup-freebsd-arm64": "4.62.5", + "@rollup/rollup-freebsd-x64": "4.62.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.5", + "@rollup/rollup-linux-arm-musleabihf": "4.62.5", + "@rollup/rollup-linux-arm64-gnu": "4.62.5", + "@rollup/rollup-linux-arm64-musl": "4.62.5", + "@rollup/rollup-linux-loong64-gnu": "4.62.5", + "@rollup/rollup-linux-loong64-musl": "4.62.5", + "@rollup/rollup-linux-ppc64-gnu": "4.62.5", + "@rollup/rollup-linux-ppc64-musl": "4.62.5", + "@rollup/rollup-linux-riscv64-gnu": "4.62.5", + "@rollup/rollup-linux-riscv64-musl": "4.62.5", + "@rollup/rollup-linux-s390x-gnu": "4.62.5", + "@rollup/rollup-linux-x64-gnu": "4.62.5", + "@rollup/rollup-linux-x64-musl": "4.62.5", + "@rollup/rollup-openbsd-x64": "4.62.5", + "@rollup/rollup-openharmony-arm64": "4.62.5", + "@rollup/rollup-win32-arm64-msvc": "4.62.5", + "@rollup/rollup-win32-ia32-msvc": "4.62.5", + "@rollup/rollup-win32-x64-gnu": "4.62.5", + "@rollup/rollup-win32-x64-msvc": "4.62.5", "fsevents": "~2.3.2" } }, @@ -5325,9 +5326,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.102.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz", - "integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==", + "version": "1.103.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.103.1.tgz", + "integrity": "sha512-9icZURbP51S6S0QGoyaeqk9uB06GNWxsFYWfH5RgpFgqK5FA8tJcM3AdVxrZEVJ7dz+L87nG95gBKf4VuaMHGw==", "dev": true, "license": "MIT", "dependencies": { @@ -5626,9 +5627,9 @@ } }, "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", "dev": true, "license": "MIT", "engines": { @@ -6536,19 +6537,19 @@ } }, "node_modules/vitest": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", - "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", + "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.10", - "@vitest/mocker": "4.1.10", - "@vitest/pretty-format": "4.1.10", - "@vitest/runner": "4.1.10", - "@vitest/snapshot": "4.1.10", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/expect": "4.1.11", + "@vitest/mocker": "4.1.11", + "@vitest/pretty-format": "4.1.11", + "@vitest/runner": "4.1.11", + "@vitest/snapshot": "4.1.11", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -6576,12 +6577,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.10", - "@vitest/browser-preview": "4.1.10", - "@vitest/browser-webdriverio": "4.1.10", - "@vitest/coverage-istanbul": "4.1.10", - "@vitest/coverage-v8": "4.1.10", - "@vitest/ui": "4.1.10", + "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-preview": "4.1.11", + "@vitest/browser-webdriverio": "4.1.11", + "@vitest/coverage-istanbul": "4.1.11", + "@vitest/coverage-v8": "4.1.11", + "@vitest/ui": "4.1.11", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -6626,16 +6627,16 @@ } }, "node_modules/vitest/node_modules/@vitest/expect": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", - "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", + "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -6644,13 +6645,13 @@ } }, "node_modules/vitest/node_modules/@vitest/mocker": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", - "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", + "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.10", + "@vitest/spy": "4.1.11", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -6671,9 +6672,9 @@ } }, "node_modules/vitest/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", "dev": true, "license": "MIT", "dependencies": { @@ -6684,9 +6685,9 @@ } }, "node_modules/vitest/node_modules/@vitest/spy": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", - "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", + "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", "dev": true, "license": "MIT", "funding": { @@ -6694,13 +6695,13 @@ } }, "node_modules/vitest/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", + "@vitest/pretty-format": "4.1.11", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, From 46cf8a03c6a793f4d045cd5bf7a899c545591eb4 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Sat, 22 Aug 2026 13:36:14 +0200 Subject: [PATCH 30/60] perf(materialbox): removed and deprecated BREAKING CHANGE: wrap the enhanced image in a dialog component --- components/dialog/___materialboxSpec.js | 37 -- components/dialog/_materialbox.scss | 42 --- components/dialog/materialbox.ts | 446 ------------------------ components/dialog/readme.md | 5 - src/index.ts | 2 +- 5 files changed, 1 insertion(+), 531 deletions(-) delete mode 100644 components/dialog/___materialboxSpec.js delete mode 100644 components/dialog/_materialbox.scss delete mode 100644 components/dialog/materialbox.ts delete mode 100644 components/dialog/readme.md diff --git a/components/dialog/___materialboxSpec.js b/components/dialog/___materialboxSpec.js deleted file mode 100644 index 3c544d14ed..0000000000 --- a/components/dialog/___materialboxSpec.js +++ /dev/null @@ -1,37 +0,0 @@ -describe('Materialbox:', () => { - const fixture = `
    - -
    `; - - beforeEach(() => XloadHtml(fixture)); - afterEach(() => XunloadFixtures()); - - describe('Materialbox opens correctly with transformed ancestor', () => { - it('Opens a correctly placed overlay when clicked', (done) => { - const transformMaterialbox = document.querySelector('#transformTest'); - M.Materialbox.init(document.querySelector('.materialboxed'), { - inDuration: 0, - outDuration: 0 - }); - // Mouse click - click(transformMaterialbox.querySelector('.materialboxed')); - setTimeout(() => { - // Check overlay is attached - const overlay = transformMaterialbox.querySelector('#materialbox-overlay'); - const overlayRect = overlay.getBoundingClientRect(); - const windowWidth = window.innerWidth; - const windowHeight = window.innerHeight; - expect(overlay).toExist('because it is generated on init'); - expect(overlay).toBeVisible('because materialbox was clicked'); - expect(overlayRect.top).toEqual(0); - expect(overlayRect.left).toEqual(0); - expect(overlayRect.width).toEqual(windowWidth); - expect(overlayRect.height).toEqual(windowHeight); - done(); - }, 10); - }); - }); -}); diff --git a/components/dialog/_materialbox.scss b/components/dialog/_materialbox.scss deleted file mode 100644 index 15f8454160..0000000000 --- a/components/dialog/_materialbox.scss +++ /dev/null @@ -1,42 +0,0 @@ -.materialboxed { - display: block; - cursor: zoom-in; - position: relative; - transition: opacity .4s; - -webkit-backface-visibility: hidden; - - &:hover { - &:not(.active) { - opacity: .8; - } - } - &.active { - cursor: zoom-out; - } -} - -#materialbox-overlay { - position:fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - background-color: var(--md-sys-color-background); - z-index: 1000; - will-change: opacity; -} - -.materialbox-caption { - position: fixed; - display: none; - color: var(--md-sys-color-on-background); - line-height: 50px; - bottom: 0; - left: 0; - width: 100%; - text-align: center; - padding: 0% 15%; - height: 50px; - z-index: 1000; - -webkit-font-smoothing: antialiased; -} \ No newline at end of file diff --git a/components/dialog/materialbox.ts b/components/dialog/materialbox.ts deleted file mode 100644 index aed6235ebd..0000000000 --- a/components/dialog/materialbox.ts +++ /dev/null @@ -1,446 +0,0 @@ -import { Utils } from '../../src/utils'; -import { BaseOptions, Component, InitElements, MElement } from '../../src/component'; - -export interface MaterialboxOptions extends BaseOptions { - /** - * Transition in duration in milliseconds. - * @default 275 - */ - inDuration: number; - /** - * Transition out duration in milliseconds. - * @default 200 - */ - outDuration: number; - /** - * Callback function called before materialbox is opened. - * @default null - */ - onOpenStart: (el: Element) => void; - /** - * Callback function called after materialbox is opened. - * @default null - */ - onOpenEnd: (el: Element) => void; - /** - * Callback function called before materialbox is closed. - * @default null - */ - onCloseStart: (el: Element) => void; - /** - * Callback function called after materialbox is closed. - * @default null - */ - onCloseEnd: (el: Element) => void; -} - -const _defaults: MaterialboxOptions = { - inDuration: 275, - outDuration: 200, - onOpenStart: null, - onOpenEnd: null, - onCloseStart: null, - onCloseEnd: null -}; - -export class Materialbox extends Component { - /** If the materialbox overlay is showing. */ - overlayActive: boolean; - /** If the materialbox is no longer being animated. */ - doneAnimating: boolean; - /** Caption, if specified. */ - caption: string; - /** Original width of image. */ - originalWidth: number; - /** Original height of image. */ - originalHeight: number; - private originInlineStyles: string; - private placeholder: HTMLElement; - private _changedAncestorList: HTMLElement[]; - private newHeight: number; - private newWidth: number; - private windowWidth: number; - private windowHeight: number; - private attrWidth: string; - private attrHeight: string; - private _overlay: HTMLElement; - private _photoCaption: HTMLElement; - - constructor(el: HTMLElement, options: Partial) { - super(el, options, Materialbox); - this.el['M_Materialbox'] = this; - - this.options = { - ...Materialbox.defaults, - ...options - }; - - this.overlayActive = false; - this.doneAnimating = true; - this.placeholder = document.createElement('div'); - this.placeholder.classList.add('material-placeholder'); - this.originalWidth = 0; - this.originalHeight = 0; - this.originInlineStyles = this.el.getAttribute('style'); - this.caption = this.el.getAttribute('data-caption') || ''; - this.el.tabIndex = 0; - // Wrap - this.el.before(this.placeholder); - this.placeholder.append(this.el); - this._setupEventHandlers(); - } - - static get defaults(): MaterialboxOptions { - return _defaults; - } - - /** - * Initializes instance of MaterialBox. - * @param el HTML element. - * @param options Component options. - */ - static init(el: HTMLElement, options?: Partial): Materialbox; - /** - * Initializes instances of MaterialBox. - * @param els HTML elements. - * @param options Component options. - */ - static init(els: InitElements, options?: Partial): Materialbox[]; - /** - * Initializes instances of MaterialBox. - * @param els HTML elements. - * @param options Component options. - */ - static init( - els: HTMLElement | InitElements, - options: Partial = {} - ): Materialbox | Materialbox[] { - return super.init(els, options, Materialbox); - } - - static getInstance(el: HTMLElement): Materialbox { - return el['M_Materialbox']; - } - - destroy() { - this._removeEventHandlers(); - this.el['M_Materialbox'] = undefined; - // Unwrap image - //this.placeholder.after(this.el).remove(); - this.placeholder.remove(); - this.el.removeAttribute('style'); - } - - private _setupEventHandlers() { - this.el.addEventListener('click', this._handleMaterialboxClick); - this.el.addEventListener('keypress', this._handleMaterialboxKeypress); - } - - private _removeEventHandlers() { - this.el.removeEventListener('click', this._handleMaterialboxClick); - this.el.removeEventListener('keypress', this._handleMaterialboxKeypress); - } - - private _handleMaterialboxClick = () => { - this._handleMaterialboxToggle(); - }; - - private _handleMaterialboxKeypress = (e: KeyboardEvent) => { - if (Utils.keys.ENTER.includes(e.key)) { - this._handleMaterialboxToggle(); - } - }; - - private _handleMaterialboxToggle = () => { - // If already modal, return to original - if (this.doneAnimating === false || (this.overlayActive && this.doneAnimating)) this.close(); - else this.open(); - }; - - private _handleWindowScroll = () => { - if (this.overlayActive) this.close(); - }; - - private _handleWindowResize = () => { - if (this.overlayActive) this.close(); - }; - - private _handleWindowEscape = (e: KeyboardEvent) => { - if (Utils.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive) this.close(); - }; - - private _makeAncestorsOverflowVisible() { - this._changedAncestorList = []; - let ancestor = this.placeholder.parentNode; - while (ancestor !== null && ancestor !== document) { - const curr = ancestor; - if (curr.style.overflow !== 'visible') { - curr.style.overflow = 'visible'; - this._changedAncestorList.push(curr); - } - ancestor = ancestor.parentNode; - } - } - - private _offset(el: HTMLElement) { - const box = el.getBoundingClientRect(); - const docElem = document.documentElement; - return { - top: box.top + window.scrollY - docElem.clientTop, - left: box.left + window.scrollX - docElem.clientLeft - }; - } - private _updateVars(): void { - this.windowWidth = window.innerWidth; - this.windowHeight = window.innerHeight; - this.caption = this.el.getAttribute('data-caption') || ''; - } - - // Image - private _animateImageIn(): void { - this.el.style.maxHeight = this.newHeight.toString() + 'px'; - this.el.style.maxWidth = this.newWidth.toString() + 'px'; - const duration = this.options.inDuration; - // from - this.el.style.transition = 'none'; - this.el.style.height = this.originalHeight + 'px'; - this.el.style.width = this.originalWidth + 'px'; - setTimeout(() => { - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.newHeight + 'px'; - this.el.style.width = this.newWidth + 'px'; - this.el.style.left = - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2 + - 'px'; - - this.el.style.top = - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2 + - 'px'; - }, 1); - - setTimeout(() => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el); - }, duration); - - /* - anim({ - targets: this.el, // image - height: [this.originalHeight, this.newHeight], - width: [this.originalWidth, this.newWidth], - left: - Utils.getDocumentScrollLeft() + - this.windowWidth / 2 - - this._offset(this.placeholder).left - - this.newWidth / 2, - top: - Utils.getDocumentScrollTop() + - this.windowHeight / 2 - - this._offset(this.placeholder).top - - this.newHeight / 2, - - duration: this.options.inDuration, - easing: 'easeOutQuad', - complete: () => { - this.doneAnimating = true; - if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el); - } - }); - */ - } - private _animateImageOut(): void { - const duration = this.options.outDuration; - // easeOutQuad - this.el.style.transition = `height ${duration}ms ease, - width ${duration}ms ease, - left ${duration}ms ease, - top ${duration}ms ease - `; - // to - this.el.style.height = this.originalWidth + 'px'; - this.el.style.width = this.originalWidth + 'px'; - this.el.style.left = '0'; - this.el.style.top = '0'; - setTimeout(() => { - this.placeholder.style.height = ''; - this.placeholder.style.width = ''; - this.placeholder.style.position = ''; - this.placeholder.style.top = ''; - this.placeholder.style.left = ''; - // Revert to width or height attribute - if (this.attrWidth) this.el.setAttribute('width', this.attrWidth.toString()); - if (this.attrHeight) this.el.setAttribute('height', this.attrHeight.toString()); - this.el.removeAttribute('style'); - if (this.originInlineStyles) this.el.setAttribute('style', this.originInlineStyles); - // Remove class - this.el.classList.remove('active'); - this.doneAnimating = true; - // Remove overflow overrides on ancestors - this._changedAncestorList.forEach((anchestor) => (anchestor.style.overflow = '')); - // onCloseEnd callback - if (typeof this.options.onCloseEnd === 'function') - this.options.onCloseEnd.call(this, this.el); - }, duration); - } - - // Caption - private _addCaption(): void { - this._photoCaption = document.createElement('div'); - this._photoCaption.classList.add('materialbox-caption'); - this._photoCaption.innerText = this.caption; - document.body.append(this._photoCaption); - this._photoCaption.style.display = 'inline'; - // Animate - this._photoCaption.style.transition = 'none'; - this._photoCaption.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '1'; - }, 1); - } - private _removeCaption(): void { - const duration = this.options.outDuration; - this._photoCaption.style.transition = `opacity ${duration}ms ease`; - this._photoCaption.style.opacity = '0'; - setTimeout(() => { - this._photoCaption.remove(); - }, duration); - } - - // Overlay - private _addOverlay(): void { - this._overlay = document.createElement('div'); - this._overlay.id = 'materialbox-overlay'; - this._overlay.addEventListener( - 'click', - () => { - if (this.doneAnimating) this.close(); - }, - { once: true } - ); - - // Put before in origin image to preserve z-index layering. - this.el.before(this._overlay); - - // Set dimensions if needed - const overlayOffset = this._overlay.getBoundingClientRect(); - this._overlay.style.width = this.windowWidth + 'px'; - this._overlay.style.height = this.windowHeight + 'px'; - this._overlay.style.left = -1 * overlayOffset.left + 'px'; - this._overlay.style.top = -1 * overlayOffset.top + 'px'; - - // Animate - this._overlay.style.transition = 'none'; - this._overlay.style.opacity = '0'; - const duration = this.options.inDuration; - setTimeout(() => { - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '1'; - }, 1); - } - private _removeOverlay(): void { - const duration = this.options.outDuration; - this._overlay.style.transition = `opacity ${duration}ms ease`; - this._overlay.style.opacity = '0'; - setTimeout(() => { - this.overlayActive = false; - this._overlay.remove(); - }, duration); - } - - /** - * Open materialbox. - */ - open = () => { - this._updateVars(); - this.originalWidth = this.el.getBoundingClientRect().width; - this.originalHeight = this.el.getBoundingClientRect().height; - // Set states - this.doneAnimating = false; - this.el.classList.add('active'); - this.overlayActive = true; - // onOpenStart callback - if (typeof this.options.onOpenStart === 'function') - this.options.onOpenStart.call(this, this.el); - // Set positioning for placeholder - this.placeholder.style.width = this.placeholder.getBoundingClientRect().width + 'px'; - this.placeholder.style.height = this.placeholder.getBoundingClientRect().height + 'px'; - this.placeholder.style.position = 'relative'; - this.placeholder.style.top = '0'; - this.placeholder.style.left = '0'; - this._makeAncestorsOverflowVisible(); - // Set css on origin - this.el.style.position = 'absolute'; - this.el.style.zIndex = '1000'; - this.el.style.willChange = 'left, top, width, height'; - // Change from width or height attribute to css - this.attrWidth = this.el.getAttribute('width'); - this.attrHeight = this.el.getAttribute('height'); - if (this.attrWidth) { - this.el.style.width = this.attrWidth + 'px'; - this.el.removeAttribute('width'); - } - if (this.attrHeight) { - this.el.style.width = this.attrHeight + 'px'; - this.el.removeAttribute('height'); - } - this._addOverlay(); - // Add and animate caption if it exists - if (this.caption !== '') this._addCaption(); - // Resize Image - const widthPercent = this.originalWidth / this.windowWidth; - const heightPercent = this.originalHeight / this.windowHeight; - this.newWidth = 0; - this.newHeight = 0; - if (widthPercent > heightPercent) { - // Width first - const ratio = this.originalHeight / this.originalWidth; - this.newWidth = this.windowWidth * 0.9; - this.newHeight = this.windowWidth * 0.9 * ratio; - } else { - // Height first - const ratio = this.originalWidth / this.originalHeight; - this.newWidth = this.windowHeight * 0.9 * ratio; - this.newHeight = this.windowHeight * 0.9; - } - this._animateImageIn(); - // Handle Exit triggers - window.addEventListener('scroll', this._handleWindowScroll); - window.addEventListener('resize', this._handleWindowResize); - window.addEventListener('keyup', this._handleWindowEscape); - }; - - /** - * Close materialbox. - */ - close = () => { - this._updateVars(); - this.doneAnimating = false; - // onCloseStart callback - if (typeof this.options.onCloseStart === 'function') - this.options.onCloseStart.call(this, this.el); - //anim.remove(this.el); - //anim.remove(this._overlay); - //if (this.caption !== '') anim.remove(this._photoCaption); - // disable exit handlers - window.removeEventListener('scroll', this._handleWindowScroll); - window.removeEventListener('resize', this._handleWindowResize); - window.removeEventListener('keyup', this._handleWindowEscape); - this._removeOverlay(); - this._animateImageOut(); - if (this.caption !== '') this._removeCaption(); - }; -} diff --git a/components/dialog/readme.md b/components/dialog/readme.md deleted file mode 100644 index afbc1ab6db..0000000000 --- a/components/dialog/readme.md +++ /dev/null @@ -1,5 +0,0 @@ -# Dialog - -TODO: Use the native html popover attribute and CSS only for this component. - -- [ ] Make a builder component diff --git a/src/index.ts b/src/index.ts index 6e816ad24a..1ada4c8f62 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,7 @@ import { Collapsible, CollapsibleOptions } from '../components/collapsible/colla import { Datepicker, DatepickerOptions } from '../components/datepicker/datepicker'; import { Dropdown, DropdownOptions } from '../components/dropdown/dropdown'; import { Forms } from '../components/textfield/forms'; -import { Materialbox, MaterialboxOptions } from '../components/dialog/materialbox'; +//import { Materialbox, MaterialboxOptions } from '../components/dialog/materialbox'; // DEPRECATED! import { Modal, ModalOptions } from '../components/dialog/modal'; import { FormSelect, FormSelectOptions } from '../components/textfield/select'; import { Sidenav, SidenavOptions } from '../components/navigation-drawer/sidenav'; From ef9f15260afde4bb47b164beef22e18e82b35df9 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Sat, 22 Aug 2026 13:38:45 +0200 Subject: [PATCH 31/60] fix: remove leftover stuff --- src/index.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1ada4c8f62..cf317c46d8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,6 @@ import { Collapsible, CollapsibleOptions } from '../components/collapsible/colla import { Datepicker, DatepickerOptions } from '../components/datepicker/datepicker'; import { Dropdown, DropdownOptions } from '../components/dropdown/dropdown'; import { Forms } from '../components/textfield/forms'; -//import { Materialbox, MaterialboxOptions } from '../components/dialog/materialbox'; // DEPRECATED! import { Modal, ModalOptions } from '../components/dialog/modal'; import { FormSelect, FormSelectOptions } from '../components/textfield/select'; import { Sidenav, SidenavOptions } from '../components/navigation-drawer/sidenav'; @@ -43,7 +42,6 @@ export { Datepicker, Dropdown, Forms, - Materialbox, Modal, Parallax, Pushpin, @@ -70,7 +68,6 @@ export interface AutoInitOptions { Collapsible?: Partial; Datepicker?: Partial; Dropdown?: Partial; - Materialbox?: Partial; Modal?: Partial; Parallax?: Partial; Pushpin?: Partial; @@ -118,7 +115,6 @@ export function AutoInit(context: HTMLElement = document.body, options?: Partial Collapsible.init(registry.Collapsible, options?.Collapsible ?? {}); Datepicker.init(registry.Datepicker, options?.Datepicker ?? {}); Dropdown.init(registry.Dropdown, options?.Dropdown ?? {}); - Materialbox.init(registry.Materialbox, options?.Materialbox ?? {}); Modal.init(registry.Modal, options?.Modal ?? {}); Parallax.init(registry.Parallax, options?.Parallax ?? {}); Pushpin.init(registry.Pushpin, options?.Pushpin ?? {}); From 16c72b1e4b4631ed0c85a75b06d0a7867cd74cf2 Mon Sep 17 00:00:00 2001 From: Daniel Wurzer Date: Thu, 17 Sep 2026 12:10:59 +0200 Subject: [PATCH 32/60] fix(appbar): add options --- components/appbar/appbar.css | 4 +++- components/appbar/appbar.mjs | 7 ++++--- components/atomic/component.mjs | 6 ++++++ sass/materialize.scss | 2 +- src/index.ts | 3 +-- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/components/appbar/appbar.css b/components/appbar/appbar.css index 60bcb2746b..09e61d726d 100644 --- a/components/appbar/appbar.css +++ b/components/appbar/appbar.css @@ -6,6 +6,7 @@ .nav-wrapper { height: 100%; + width: 100%; background-color: var(--md-sys-color-surface); padding-left: 4px; padding-right: 4px; @@ -43,7 +44,8 @@ .navbar .brand-logo { color: var(--md-sys-color-on-surface); font-size: var(--appbar-title-font-size); - display: inline-block; + display: flex; + align-items: center; padding: 0; } diff --git a/components/appbar/appbar.mjs b/components/appbar/appbar.mjs index 62b3916041..ac87aa32e9 100644 --- a/components/appbar/appbar.mjs +++ b/components/appbar/appbar.mjs @@ -8,7 +8,7 @@ class AppBar extends Component { /** * - * @param {{isFixed: Boolean = false}} options + * @param {{isFixed: Boolean = false, hasContainer: Boolean = true}} options */ constructor(options) { super(options); @@ -52,10 +52,11 @@ class AppBar extends Component {
  • refresh
  • more_vert
  • */ - const html = `