diff --git a/addon/-private/popover.js b/addon/-private/popover.js new file mode 100644 index 000000000..c040b7748 --- /dev/null +++ b/addon/-private/popover.js @@ -0,0 +1,156 @@ +/** + Turns an element into an anchored, non-modal popover using the browser's + Popover API (for top-layer rendering) and CSS anchor positioning (for + placement relative to an anchor element). + + The element must carry a `popover="manual"` attribute and the `docs-popover` + class (see `addon/styles/components/_docs-popover.scss`). Placement is + driven by CSS via the `data-docs-placement` attribute set here. + + Browsers that support the Popover API but not CSS anchor positioning + (Safari 17/18, Firefox < 147) fall back to positioning the popover with + inline `top`/`left`/`right` styles computed from the anchor's bounding box. + + @param {HTMLElement} element the popover element + @param {Object} options + @param {string|Element} options.anchor the element (or selector) the popover is positioned against + @param {string|Element} [options.trigger=options.anchor] element (or selector) whose clicks never count as "outside" + @param {'bottom-start'|'bottom-end'} [options.placement='bottom-start'] which edges to align + @param {Function} [options.onClose] called when the user clicks outside or presses Escape + @return {Function} a teardown function + @private +*/ +export function openAnchoredPopover( + element, + { anchor, trigger = anchor, placement = 'bottom-start', onClose } = {}, +) { + let anchorElement = resolve(anchor); + let triggerElement = resolve(trigger) || anchorElement; + let teardowns = []; + + element.dataset.docsPlacement = placement; + + if (anchorElement) { + if (supportsAnchorPositioning()) { + teardowns.push(linkAnchor(element, anchorElement)); + } else { + teardowns.push(positionManually(element, anchorElement, placement)); + } + } + + if (typeof element.showPopover === 'function') { + element.showPopover(); + teardowns.push(() => { + if (element.isConnected && element.matches(':popover-open')) { + element.hidePopover(); + } + }); + } + + if (onClose) { + let onPointerDown = (event) => { + let { target } = event; + let isInside = + element.contains(target) || + anchorElement?.contains(target) || + triggerElement?.contains(target); + + if (!isInside) { + onClose(); + } + }; + let onKeyDown = (event) => { + if (event.key === 'Escape') { + onClose(); + } + }; + + document.addEventListener('pointerdown', onPointerDown); + document.addEventListener('keydown', onKeyDown); + teardowns.push(() => { + document.removeEventListener('pointerdown', onPointerDown); + document.removeEventListener('keydown', onKeyDown); + }); + } + + return () => { + teardowns.reverse().forEach((teardown) => teardown()); + teardowns = []; + }; +} + +function resolve(elementOrSelector) { + if (typeof elementOrSelector === 'string') { + return document.querySelector(elementOrSelector); + } + return elementOrSelector || null; +} + +export function supportsAnchorPositioning() { + return ( + typeof CSS !== 'undefined' && + CSS.supports?.('position-anchor', '--docs-popover') && + CSS.supports?.('position-area', 'bottom') + ); +} + +let anchorCounter = 0; + +// Associates the popover with its anchor through CSS anchor positioning. The +// actual placement (`position-area`) lives in the stylesheet. +function linkAnchor(element, anchorElement) { + let name = anchorElement.style.anchorName; + let ownsName = false; + + if (!name || name === 'none') { + name = `--docs-popover-anchor-${anchorCounter++}`; + anchorElement.style.anchorName = name; + ownsName = true; + } + + element.style.positionAnchor = name; + + return () => { + element.style.positionAnchor = ''; + if (ownsName) { + anchorElement.style.anchorName = ''; + } + }; +} + +// Fallback for browsers without CSS anchor positioning: mirror the anchor's +// bounding box into inline styles, and keep them fresh on scroll and resize. +function positionManually(element, anchorElement, placement) { + let viewportGap = 8; + + let update = () => { + let anchorRect = anchorElement.getBoundingClientRect(); + let { innerWidth, innerHeight } = window; + + element.style.top = `${anchorRect.bottom}px`; + element.style.bottom = 'auto'; + element.style.maxHeight = `${Math.max(0, innerHeight - anchorRect.bottom - viewportGap)}px`; + + if (placement === 'bottom-end') { + let right = Math.max(0, innerWidth - anchorRect.right); + element.style.right = `${Math.min(right, Math.max(0, innerWidth - element.offsetWidth))}px`; + element.style.left = 'auto'; + } else { + let left = Math.max(0, anchorRect.left); + element.style.left = `${Math.min(left, Math.max(0, innerWidth - element.offsetWidth))}px`; + element.style.right = 'auto'; + } + }; + + update(); + window.addEventListener('resize', update); + window.addEventListener('scroll', update, true); + + return () => { + window.removeEventListener('resize', update); + window.removeEventListener('scroll', update, true); + ['top', 'bottom', 'left', 'right', 'maxHeight'].forEach((property) => { + element.style[property] = ''; + }); + }; +} diff --git a/addon/components/docs-header/index.hbs b/addon/components/docs-header/index.hbs index c6d1fdfbb..21cd5d873 100644 --- a/addon/components/docs-header/index.hbs +++ b/addon/components/docs-header/index.hbs @@ -23,7 +23,7 @@ - + {{#if (eq this.currentVersion.key this.config.latestVersionName)}} diff --git a/addon/components/docs-header/search-results/index.hbs b/addon/components/docs-header/search-results/index.hbs index 998572f03..ee371aa56 100644 --- a/addon/components/docs-header/search-results/index.hbs +++ b/addon/components/docs-header/search-results/index.hbs @@ -4,13 +4,15 @@ ...attributes > {{#if (and this.trimmedQuery this.search.isIdle)}} -
    {{/each}}
-
+ {{/if}} - \ No newline at end of file + diff --git a/addon/components/docs-header/version-selector/index.hbs b/addon/components/docs-header/version-selector/index.hbs index 9a2b9d3c4..69d0ceab0 100644 --- a/addon/components/docs-header/version-selector/index.hbs +++ b/addon/components/docs-header/version-selector/index.hbs @@ -1,14 +1,16 @@ - -
    +
      {{#each this.sortedVersions as |version index|}}
    • {{/each}}
    - \ No newline at end of file + diff --git a/addon/components/docs-keyboard-shortcuts/index.hbs b/addon/components/docs-keyboard-shortcuts/index.hbs index 7efc87b8f..b9798d185 100644 --- a/addon/components/docs-keyboard-shortcuts/index.hbs +++ b/addon/components/docs-keyboard-shortcuts/index.hbs @@ -1,23 +1,26 @@ {{#if this.isShowingKeyboardShortcuts}} -
    @@ -184,5 +187,5 @@
    - + {{/if}} \ No newline at end of file diff --git a/addon/components/docs-keyboard-shortcuts/index.js b/addon/components/docs-keyboard-shortcuts/index.js index 55041f12d..ebe9c27e3 100644 --- a/addon/components/docs-keyboard-shortcuts/index.js +++ b/addon/components/docs-keyboard-shortcuts/index.js @@ -54,9 +54,14 @@ export default class DocsKeyboardShortcutsComponent extends Component { } } + // The native already closes itself on Escape (and fires `close`, + // which the {{docs-dialog}} modifier routes here). Keeping the key binding + // makes the behaviour explicit and lets it be exercised with synthetic key + // events in tests. @onKey('Escape', { event: 'keyup' }) + @action hideKeyboardShortcuts() { - if (!formElementHasFocus() && this.isShowingKeyboardShortcuts) { + if (this.isShowingKeyboardShortcuts) { this.isShowingKeyboardShortcuts = false; } } diff --git a/addon/components/docs-modal-dialog.js b/addon/components/docs-modal-dialog.js deleted file mode 100644 index 105991929..000000000 --- a/addon/components/docs-modal-dialog.js +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable ember/classic-decorator-hooks */ -import ModalDialog from 'ember-modal-dialog/components/modal-dialog'; -import { getOwner } from '@ember/application'; - -export default class DocsModalDialog extends ModalDialog { - init() { - super.init(...arguments); - - const config = getOwner(this).resolveRegistration('config:environment'); - let fastboot = getOwner(this).lookup('service:fastboot'); - this.set( - 'renderInPlace', - config.environment === 'test' || fastboot?.isFastBoot, - ); - } -} diff --git a/addon/modifiers/docs-dialog.js b/addon/modifiers/docs-dialog.js new file mode 100644 index 000000000..455e50d4f --- /dev/null +++ b/addon/modifiers/docs-dialog.js @@ -0,0 +1,60 @@ +import Modifier from 'ember-modifier'; +import { registerDestructor } from '@ember/destroyable'; + +/** + Opens a native `` as a modal for as long as it is rendered. + + ```hbs + + ... + + ``` + + On insert the dialog is shown with `showModal()` and focused, so the page + behind it is inert and screen readers announce it. `onClose` is called when + the dialog closes natively (Escape, `closedby="any"`, a form with + `method="dialog"`, or `dialog.close()`) and when the backdrop is clicked in + browsers that do not support `closedby`; the caller is expected to stop + rendering the dialog in response. + + @class DocsDialogModifier + @private +*/ +export default class DocsDialogModifier extends Modifier { + _removeListeners = null; + + constructor(owner, args) { + super(owner, args); + registerDestructor(this, () => this._removeListeners?.()); + } + + modify(dialog, positional, { onClose }) { + if (!dialog.open) { + dialog.showModal(); + dialog.focus(); + } + + this._removeListeners?.(); + this._removeListeners = null; + + if (!onClose) { + return; + } + + let handleClose = () => onClose(); + // A click whose target is the element itself landed on its + // ::backdrop, i.e. outside the dialog box. + let handleClick = (event) => { + if (event.target === dialog) { + onClose(); + } + }; + + dialog.addEventListener('close', handleClose); + dialog.addEventListener('click', handleClick); + this._removeListeners = () => { + dialog.removeEventListener('close', handleClose); + dialog.removeEventListener('click', handleClick); + }; + } +} diff --git a/addon/modifiers/docs-popover.js b/addon/modifiers/docs-popover.js new file mode 100644 index 000000000..9e4f67251 --- /dev/null +++ b/addon/modifiers/docs-popover.js @@ -0,0 +1,48 @@ +import Modifier from 'ember-modifier'; +import { registerDestructor } from '@ember/destroyable'; +import { openAnchoredPopover } from 'ember-cli-addon-docs/-private/popover'; + +/** + Shows the element as an anchored popover for as long as it is rendered. + + ```hbs +
    +
      + ... +
    +
    + ``` + + The popover is opened when the element is inserted, re-opened (with the new + options) whenever one of the named arguments changes, and hidden again when + the element is removed. See `openAnchoredPopover` for the available options. + + @class DocsPopoverModifier + @private +*/ +export default class DocsPopoverModifier extends Modifier { + _close = null; + + constructor(owner, args) { + super(owner, args); + registerDestructor(this, () => this.close()); + } + + modify(element, positional, named) { + this.close(); + this._close = openAnchoredPopover(element, named); + } + + close() { + this._close?.(); + this._close = null; + } +} diff --git a/addon/styles/addon.scss b/addon/styles/addon.scss index fd0ae7be3..95385796b 100644 --- a/addon/styles/addon.scss +++ b/addon/styles/addon.scss @@ -14,9 +14,9 @@ @include meta.load-css('components/docs-header-search-box'); @include meta.load-css('components/docs-hero'); @include meta.load-css('components/docs-keyboard-shortcuts'); +@include meta.load-css('components/docs-popover'); @include meta.load-css('components/docs-viewer-x-current-page-index'); @include meta.load-css('components/docs-viewer-x-nav'); -@include meta.load-css('components/modal-dialog'); @include meta.load-css('syntax'); diff --git a/addon/styles/components/_docs-keyboard-shortcuts.scss b/addon/styles/components/_docs-keyboard-shortcuts.scss index 032723975..d88c104e6 100644 --- a/addon/styles/components/_docs-keyboard-shortcuts.scss +++ b/addon/styles/components/_docs-keyboard-shortcuts.scss @@ -12,29 +12,29 @@ box-shadow: inset 0 -1px 0 #c6cbd1; } +// A native shown with showModal(): the browser renders it in the top +// layer, makes the rest of the page inert, traps focus and closes on Escape. .docs-fullscreen-modal { - .ember-modal-overlay { - z-index: 50; + background: white; + width: 600px; + max-width: calc(100vw - 2rem); + padding: 0; + border: 0; + border-radius: 3px; + box-shadow: 0 0 14px rgba(0,0,0,.24), 0 14px 28px rgba(0,0,0,.48); + // Sit 100px from the top of the viewport (not vertically centered) and + // scroll internally when taller than the remaining space. + margin: 100px auto auto; + max-height: calc(100vh - 200px); + overflow: auto; + color: inherit; + + &::backdrop { background: rgba(#1b1f23, .5); - position: fixed; - top: 0; - bottom: 0; - right: 0; - left: 0; - overflow: scroll; - display: flex; - justify-content: center; - align-items: flex-start; } - .ember-modal-dialog { - background: white; - width: 600px; - border-radius: 3px; - box-shadow: 0 0 14px rgba(0,0,0,.24), 0 14px 28px rgba(0,0,0,.48); - height: auto; - display: inline-block; - margin-top: 100px; - margin-bottom: 100px; + + &:focus { + outline: none; } &__header { @@ -45,6 +45,10 @@ } &__close-button { margin-left: auto; + padding: 0; + border: 0; + background: none; + cursor: pointer; text-decoration: none; color: #999; font-size: 26px; @@ -81,3 +85,8 @@ text-align: left; } } + +// Keep the page from scrolling behind the open dialog. +body:has(.docs-fullscreen-modal[open]) { + overflow: hidden; +} diff --git a/addon/styles/components/_docs-popover.scss b/addon/styles/components/_docs-popover.scss new file mode 100644 index 000000000..1a988f9e2 --- /dev/null +++ b/addon/styles/components/_docs-popover.scss @@ -0,0 +1,62 @@ +// Anchored, non-modal popovers (search results, version selector). +// +// The popover element is a plain wrapper: it uses the Popover API to render in +// the top layer (so it is never clipped by the header's overflow) and CSS +// anchor positioning to sit next to its anchor. Its single child carries the +// visual styling (background, shadow, rounding) and scrolls when the popover +// is taller than the space below the anchor. See `addon/-private/popover.js` +// for the JS side, including the fallback for browsers without anchor +// positioning. +.docs-popover { + // Undo the UA stylesheet for [popover] so the wrapper is invisible and can + // be aligned to its anchor. Overflow stays visible so the child's shadow is + // not clipped; the child scrolls instead (see below). + position: fixed; + inset: auto; + margin: 0; + padding: 0; + border: 0; + background: transparent; + color: inherit; + overflow: visible; + display: flex; + flex-direction: column; + + > * { + min-height: 0; + overflow-y: auto; + } + + // Never extend past the bottom of the viewport; scroll instead. The + // containing block of an anchored popover is the position-area box, so + // 100% here is the space between the anchor and the viewport edge. + max-height: calc(100% - 0.5rem); + + // Align the popover's start/end edge with the anchor's. When that would + // overflow the viewport, first slide it so it hugs the viewport edge (what + // ember-tether's "pin" constraint used to do), then flip to the other side. + &[data-docs-placement="bottom-start"] { + position-area: bottom span-right; + position-try-fallbacks: --docs-popover-pin-end, flip-inline; + } + + &[data-docs-placement="bottom-end"] { + position-area: bottom span-left; + position-try-fallbacks: --docs-popover-pin-start, flip-inline; + } +} + +@position-try --docs-popover-pin-end { + position-area: bottom span-all; + inset-inline: auto 0; +} + +@position-try --docs-popover-pin-start { + position-area: bottom span-all; + inset-inline: 0 auto; +} + +.docs-version-selector { + margin-top: 0.5rem; + max-height: calc(100% - 1rem); +} diff --git a/addon/styles/components/_modal-dialog.scss b/addon/styles/components/_modal-dialog.scss deleted file mode 100644 index ca2c33be1..000000000 --- a/addon/styles/components/_modal-dialog.scss +++ /dev/null @@ -1,3 +0,0 @@ -.ember-modal-dialog { - @apply docs-z-50; -} diff --git a/app/components/docs-modal-dialog.js b/app/components/docs-modal-dialog.js deleted file mode 100644 index 4100a0b84..000000000 --- a/app/components/docs-modal-dialog.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'ember-cli-addon-docs/components/docs-modal-dialog'; diff --git a/app/modifiers/docs-dialog.js b/app/modifiers/docs-dialog.js new file mode 100644 index 000000000..5317cb21d --- /dev/null +++ b/app/modifiers/docs-dialog.js @@ -0,0 +1 @@ +export { default } from 'ember-cli-addon-docs/modifiers/docs-dialog'; diff --git a/app/modifiers/docs-popover.js b/app/modifiers/docs-popover.js new file mode 100644 index 000000000..05f79f7b4 --- /dev/null +++ b/app/modifiers/docs-popover.js @@ -0,0 +1 @@ +export { default } from 'ember-cli-addon-docs/modifiers/docs-popover'; diff --git a/package.json b/package.json index 8bed9acc5..d2c696d98 100644 --- a/package.json +++ b/package.json @@ -63,12 +63,11 @@ "ember-code-snippet": "^3.0.0", "ember-concurrency": "^5.1.0", "ember-keyboard": "^9.0.4", - "ember-modal-dialog": "^5.0.0", + "ember-modifier": "^4.2.0", "ember-router-generator": "^2.0.0", "ember-set-helper": "^3.1.0", "ember-svg-jar": "^2.7.1", "ember-template-imports": "^4.3.0", - "ember-tether": "^3.1.0", "ember-truth-helpers": "^5.0.0", "execa": "5.1.1", "fs-extra": "^11.3.2", @@ -191,8 +190,7 @@ "webpack": "$webpack" }, "onlyBuiltDependencies": [ - "@parcel/watcher", - "ember-modal-dialog" + "@parcel/watcher" ] }, "engines": { @@ -211,9 +209,6 @@ "ember-cli-htmlbars", "ember-svg-jar", "ember-code-snippet" - ], - "after": [ - "ember-modal-dialog" ] }, "release-it": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04a8c98f0..637e07697 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,9 +117,9 @@ importers: ember-keyboard: specifier: ^9.0.4 version: 9.0.4(@babel/core@7.29.0)(@ember/test-helpers@4.0.5(@babel/core@7.29.0)(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))) - ember-modal-dialog: - specifier: ^5.0.0 - version: 5.0.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))(ember-tether@3.1.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))(webpack@5.103.0))(liquid-fire@0.37.1(@babel/core@7.29.0)(velocity-animate@1.5.2))(velocity-animate@1.5.2) + ember-modifier: + specifier: ^4.2.0 + version: 4.2.2(@babel/core@7.29.0) ember-router-generator: specifier: ^2.0.0 version: 2.0.0 @@ -132,9 +132,6 @@ importers: ember-template-imports: specifier: ^4.3.0 version: 4.4.0 - ember-tether: - specifier: ^3.1.0 - version: 3.1.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))(webpack@5.103.0) ember-truth-helpers: specifier: ^5.0.0 version: 5.0.0 @@ -554,12 +551,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-class-features-plugin@7.28.6': - resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-create-regexp-features-plugin@7.28.5': resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} engines: {node: '>=6.9.0'} @@ -571,11 +562,6 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-define-polyfill-provider@0.6.8': - resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-environment-visitor@7.24.7': resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} engines: {node: '>=6.9.0'} @@ -624,10 +610,6 @@ packages: resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} - engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.27.1': resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} engines: {node: '>=6.9.0'} @@ -640,12 +622,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.28.6': - resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} @@ -718,12 +694,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': - resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/plugin-proposal-class-properties@7.18.6': resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} @@ -737,12 +707,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-proposal-decorators@7.29.0': - resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-proposal-private-methods@7.18.6': resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} @@ -769,36 +733,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-decorators@7.28.6': - resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.27.1': resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.28.6': - resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.27.1': resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.28.6': - resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-private-property-in-object@7.14.5': resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} @@ -811,12 +757,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.28.6': - resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6': resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} @@ -835,24 +775,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.29.0': - resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.27.1': resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.28.6': - resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.27.1': resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} engines: {node: '>=6.9.0'} @@ -865,60 +793,30 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.28.6': - resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.27.1': resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.28.6': - resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.28.3': resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-class-static-block@7.28.6': - resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.4': resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-classes@7.28.6': - resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.27.1': resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.28.6': - resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.28.5': resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} engines: {node: '>=6.9.0'} @@ -931,12 +829,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.28.6': - resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.27.1': resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} engines: {node: '>=6.9.0'} @@ -949,12 +841,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': - resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/plugin-transform-dynamic-import@7.27.1': resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} engines: {node: '>=6.9.0'} @@ -967,24 +853,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-explicit-resource-management@7.28.6': - resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.28.5': resolution: {integrity: sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.28.6': - resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-export-namespace-from@7.27.1': resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} engines: {node: '>=6.9.0'} @@ -1009,12 +883,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.28.6': - resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.27.1': resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} engines: {node: '>=6.9.0'} @@ -1027,12 +895,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.28.6': - resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.27.1': resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} engines: {node: '>=6.9.0'} @@ -1051,24 +913,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.28.6': - resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.28.5': resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.29.0': - resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-umd@7.27.1': resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} engines: {node: '>=6.9.0'} @@ -1081,12 +931,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': - resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/plugin-transform-new-target@7.27.1': resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} engines: {node: '>=6.9.0'} @@ -1099,36 +943,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': - resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.27.1': resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.28.6': - resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.4': resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.6': - resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.27.1': resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} engines: {node: '>=6.9.0'} @@ -1141,24 +967,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.28.6': - resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.28.5': resolution: {integrity: sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.28.6': - resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.27.7': resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} engines: {node: '>=6.9.0'} @@ -1171,24 +985,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.28.6': - resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.27.1': resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.28.6': - resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.27.1': resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} engines: {node: '>=6.9.0'} @@ -1201,24 +1003,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.29.0': - resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regexp-modifiers@7.27.1': resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-regexp-modifiers@7.28.6': - resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/plugin-transform-reserved-words@7.27.1': resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} engines: {node: '>=6.9.0'} @@ -1231,12 +1021,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.29.0': - resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.27.1': resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} engines: {node: '>=6.9.0'} @@ -1249,12 +1033,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.28.6': - resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-sticky-regex@7.27.1': resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} engines: {node: '>=6.9.0'} @@ -1279,12 +1057,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.6': - resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.5.5': resolution: {integrity: sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w==} peerDependencies: @@ -1302,12 +1074,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.28.6': - resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-regex@7.27.1': resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} engines: {node: '>=6.9.0'} @@ -1320,24 +1086,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-unicode-sets-regex@7.28.6': - resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/preset-env@7.28.5': resolution: {integrity: sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-env@7.29.2': - resolution: {integrity: sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/preset-modules@0.1.6-no-external-plugins': resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: @@ -1465,16 +1219,6 @@ packages: resolution: {integrity: sha512-HMQqZoBb16I4NyHfQglIYjopSG6folcEJah2WPa0FuolWRA/8cS5ozQmFK5BQx7cijTQJxj6viLpQK9KrXuYdw==} engines: {node: '>= 20.19'} - '@ember/render-modifiers@2.1.0': - resolution: {integrity: sha512-LruhfoDv2itpk0fA0IC76Sxjcnq/7BC6txpQo40hOko8Dn6OxwQfxkPIbZGV0Cz7df+iX+VJrcYzNIvlc3w2EQ==} - engines: {node: 12.* || 14.* || >= 16} - peerDependencies: - '@glint/template': ^1.0.2 - ember-source: ~6.2.0 - peerDependenciesMeta: - '@glint/template': - optional: true - '@ember/render-modifiers@3.0.0': resolution: {integrity: sha512-gJztS8dI7Jt8ohFQptEDJAgpl9DG84IpqwQoR1JDpVIBy2uLbf8KFD6S3h3LfyMsgJce6G38cOvyQv6BDgcnsA==} engines: {node: '>= 18'} @@ -1507,15 +1251,6 @@ packages: '@glint/template': optional: true - '@embroider/macros@1.20.2': - resolution: {integrity: sha512-WJWSkG9vIL0s93vKwtNFqqAOCOflNkWNpqsC7VAqXeeTKNpCc7wtdOhPkNGJpb52CEt7vlQ5R/zMyCfGAB7MEA==} - engines: {node: 12.* || 14.* || >= 16} - peerDependencies: - '@glint/template': ^1.0.0 - peerDependenciesMeta: - '@glint/template': - optional: true - '@embroider/reverse-exports@0.2.0': resolution: {integrity: sha512-WFsw8nQpHZiWGEDYpa/A79KEFfTisqteXbY+jg9eZiww1r1G+LZvsmdszDp86TkotUSCqrMbK/ewn0jR1CJmqg==} engines: {node: 12.* || 14.* || >= 16} @@ -1528,10 +1263,6 @@ packages: resolution: {integrity: sha512-d7RQwDwqqHo7YvjE9t1rtIrCCYtbSoO0uRq2ikVhRh4hGS5OojZNu2ZtS0Wqrg+V72CRtMFr/hibTvHNsRM2Lg==} engines: {node: 12.* || 14.* || >= 16} - '@embroider/shared-internals@3.0.2': - resolution: {integrity: sha512-/SusdG+zgosc3t+9sPFVKSFOYyiSgLfXOT6lYNWoG1YtnhWDxlK4S8leZ0jhcVjemdaHln5rTyxCnq8oFLxqpQ==} - engines: {node: 12.* || 14.* || >= 16} - '@embroider/test-setup@4.0.0': resolution: {integrity: sha512-1S3Ebk0CEh3XDqD93AWSwQZBCk+oGv03gtkaGgdgyXGIR7jrVyDgEnEuslN/hJ0cuU8TqhiXrzHMw7bJwIGhWw==} engines: {node: 12.* || 14.* || >= 16} @@ -1547,19 +1278,6 @@ packages: '@embroider/webpack': optional: true - '@embroider/util@1.13.5': - resolution: {integrity: sha512-rHhGUzAQ5iOr5Swvk7yaarVe5SJtcjK2t/C8ts9agWfhTq4DVfy8+axF0KOf1jALRiJao3l9ALRGd6letKw2ZQ==} - engines: {node: 12.* || 14.* || >= 16} - peerDependencies: - '@glint/environment-ember-loose': ^1.0.0 - '@glint/template': ^1.0.0 - ember-source: ~6.2.0 - peerDependenciesMeta: - '@glint/environment-ember-loose': - optional: true - '@glint/template': - optional: true - '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2177,36 +1895,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.1': resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.1': resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.1': resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.1': resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.1': resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.1': resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} @@ -2855,39 +2579,21 @@ packages: babel-plugin-module-resolver@5.0.2: resolution: {integrity: sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==} - babel-plugin-module-resolver@5.0.3: - resolution: {integrity: sha512-h8h6H71ZvdLJZxZrYkaeR30BojTaV7O9GfqacY14SNj5CNB8ocL9tydNzTC0JrnNN7vY3eJhwCmkDj7tuEUaqQ==} - babel-plugin-polyfill-corejs2@0.4.14: resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs2@0.4.17: - resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.13.0: resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.14.2: - resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.5: resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.8: - resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-syntax-dynamic-import@6.18.0: resolution: {integrity: sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA==} @@ -3810,9 +3516,6 @@ packages: core-js-compat@3.47.0: resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} - core-js-compat@3.49.0: - resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} - core-js@2.6.12: resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. @@ -4028,9 +3731,6 @@ packages: decorator-transforms@2.3.0: resolution: {integrity: sha512-jo8c1ss9yFPudHuYYcrJ9jpkDZIoi+lOGvt+Uyp9B+dz32i50icRMx9Bfa8hEt7TnX1FyKWKkjV+cUdT/ep2kA==} - decorator-transforms@2.3.1: - resolution: {integrity: sha512-PDOk74Zqqy0946Lx4ckXxbgG6uhPScOICtrxL/pXmfznxchqNee0TaJISClGJQe6FeT8ohGqsOgdjfahm4FwEw==} - deep-eql@0.1.3: resolution: {integrity: sha512-6sEotTRGBFiNcqVoeHwnfopbSpi5NbH1VWJmYCVkmxMmaVTT0bUTrNaGyBwhgP4MZL012W/mkzIn3Da+iDYweg==} @@ -4272,12 +3972,6 @@ packages: peerDependencies: '@babel/core': ^7.12.0 - ember-cli-babel@8.3.1: - resolution: {integrity: sha512-Pxm5JP0jQ6fCBlXuh1BFmhrg2/5YXjhf16JI/n8ReOR6Nl+fEbudMpdO69LlqZRsMmTgdjCRmfSxMh26Wsw/rw==} - engines: {node: 16.* || 18.* || >= 20} - peerDependencies: - '@babel/core': ^7.12.0 - ember-cli-blueprint-test-helpers@0.19.2: resolution: {integrity: sha512-otCKdGcNFK0+MkQo+LLjYbRD9EerApH6Z/odvvlL1hxrN+owHMV5E+jI2rbtdvNEH0/6w5ZqjH4kS232fvtCxQ==} engines: {node: 6.* || 8.* || >= 10.*} @@ -4460,23 +4154,6 @@ packages: peerDependencies: ember-source: ~6.2.0 - ember-modal-dialog@5.0.0: - resolution: {integrity: sha512-+POBUIIeRjgsJBO9VC11Qv9OQt6AnW7BPX/wHB/wmICMIvMTOWPPfjSs49YOuHjMCS/ovCBHCixmPuiIlwUrFQ==} - engines: {node: 18.* || >= 20} - peerDependencies: - ember-tether: ^3.0.0 - liquid-fire: ^0.37.1 - liquid-tether: ^3.0.0 - liquid-wormhole: ^6.0.0 - velocity-animate: ^1.5.2 - peerDependenciesMeta: - ember-tether: - optional: true - liquid-tether: - optional: true - liquid-wormhole: - optional: true - ember-modifier-manager-polyfill@1.2.0: resolution: {integrity: sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA==} engines: {node: 6.* || 8.* || >= 10.*} @@ -4484,9 +4161,6 @@ packages: ember-modifier@4.2.2: resolution: {integrity: sha512-pPYBAGyczX0hedGWQFQOEiL9s45KS9efKxJxUQkMLjQyh+1Uef1mcmAGsdw2KmvNupITkE/nXxmVO1kZ9tt3ag==} - ember-modifier@4.3.0: - resolution: {integrity: sha512-O0rirSLQbGg0VJ/NqoQ4uN1bh2iAekZC/Ykma+FkjCM2ofrO38u+d8n3+AK6uVWeMJmogGX2KL+Is5fofoInJg==} - ember-qunit@9.0.4: resolution: {integrity: sha512-rv6gKvrdXdPBTdSZC5co82eIcDWWVR7RjafU/c+5TTz290oXhIHPoVuZbcO2F5RiAqkTW0jKzwkCP8y+2tCjFw==} peerDependencies: @@ -4544,12 +4218,6 @@ packages: resolution: {integrity: sha512-mIgjzv5PE+z64p1+o8eYkLHqkJY1g4BD93vgfE+ZTAvarIsJxGO8WmmZ7xCkmCM0xB4Idf0duR7IhLRsTg/81w==} engines: {node: 18.* || 20.* || >= 22.*} - ember-tether@3.1.0: - resolution: {integrity: sha512-PbCLEbjLj6d22Jj+7dLHpV0grciVv47/mpULKUaHjcvk1d218MgvlFXfJhWqbt+wPl/OBbqcgCXAqwpwZ+7d7g==} - engines: {node: '>= 14'} - peerDependencies: - ember-source: ~6.2.0 - ember-truth-helpers@5.0.0: resolution: {integrity: sha512-PnQd6D6hvlNC3k6gBu0SC2cvfXX6wH6W0nToomIIoxqyrD5cllk0zBh/j/1H0KsczVCWeuF9PWj5xJgL4jQAGg==} @@ -4561,10 +4229,6 @@ packages: resolution: {integrity: sha512-ZYVKYWMnrHSD3vywo7rV76kPCOC9ATIEnGGG/PEKfCcFE0lB26jltRDnOrhORfLKq0JFp62fFxC/4940U+MwRQ==} engines: {node: 16.* || >= 18.*} - ember-wormhole@0.6.1: - resolution: {integrity: sha512-PIKLhWsWaw6W9a6kRGLFRVLdzw5f2wRkaTXOlM19PvakvchV969l67Ee52YwwKS69iYv2052TNaJ9pA3AeWmuw==} - engines: {node: 10.* || >= 12} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -6214,11 +5878,6 @@ packages: linkify-it@4.0.1: resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} - liquid-fire@0.37.1: - resolution: {integrity: sha512-ULu4OlcqSB1iJp+/NPPqJCi8XgiMDHuhjKLsazsQTb4xB15FI2HFV/DCfzvFxfUtoaeKlnmxsrUATBmPww0Kgg==} - peerDependencies: - velocity-animate: ^1.5.2 - livereload-js@3.4.1: resolution: {integrity: sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==} @@ -8451,9 +8110,6 @@ packages: engines: {node: '>= 7.*'} hasBin: true - tether@2.0.0: - resolution: {integrity: sha512-iAkyBhwILpLIvkwzO5w5WUBtpYwxvzLRTO+sbzF3Uy7X4zznsy73v2b4sOQHXE3CQHeSNtB/YMU2Nn9tocbeBQ==} - textextensions@2.6.0: resolution: {integrity: sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==} engines: {node: '>=0.8'} @@ -8830,9 +8486,6 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - velocity-animate@1.5.2: - resolution: {integrity: sha512-m6EXlCAMetKztO1ppBhGU1/1MR3IiEevO6ESq6rcrSQ3Q77xYSW13jkfXW88o4xMrkXJhy/U7j4wFR/twMB0Eg==} - w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} deprecated: Use your platform's native performance.now() and performance.timeOrigin. @@ -9268,19 +8921,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.29.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9317,17 +8957,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3(supports-color@8.1.1) - lodash.debounce: 4.0.8 - resolve: 1.22.11 - transitivePeerDependencies: - - supports-color - '@babel/helper-environment-visitor@7.24.7': dependencies: '@babel/types': 7.28.5 @@ -9406,8 +9035,6 @@ snapshots: '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9444,15 +9071,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: '@babel/traverse': 7.29.0 @@ -9566,14 +9184,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9608,15 +9218,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9671,11 +9272,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9686,11 +9282,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9701,11 +9292,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9726,11 +9312,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9771,15 +9352,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9798,15 +9370,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9827,11 +9390,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9848,14 +9406,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9872,14 +9422,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9904,18 +9446,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-globals': 7.28.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9928,12 +9458,6 @@ snapshots: '@babel/helper-plugin-utils': 7.27.1 '@babel/template': 7.28.6 - '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/template': 7.28.6 - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9962,12 +9486,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -9990,12 +9508,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10022,14 +9534,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10040,11 +9544,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10099,11 +9598,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10124,11 +9618,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10171,14 +9660,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10199,16 +9680,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10237,12 +9708,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10258,15 +9723,10 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)': dependencies: @@ -10278,11 +9738,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10305,17 +9760,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10342,11 +9786,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10363,14 +9802,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10397,14 +9828,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10423,15 +9846,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10452,11 +9866,6 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10469,12 +9878,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10509,18 +9912,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10547,14 +9938,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10607,17 +9990,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-typescript@7.5.5(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 @@ -10649,12 +10021,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10679,12 +10045,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-env@7.28.5(@babel/core@7.28.5)': dependencies: '@babel/compat-data': 7.28.5 @@ -10837,82 +10197,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-env@7.29.2(@babel/core@7.29.0)': - dependencies: - '@babel/compat-data': 7.29.0 - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) - '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) - core-js-compat: 3.49.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -11068,16 +10352,6 @@ snapshots: - '@types/node' - supports-color - '@ember/render-modifiers@2.1.0(@babel/core@7.29.0)(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))': - dependencies: - '@embroider/macros': 1.19.5(@babel/core@7.29.0) - ember-cli-babel: 8.2.0(@babel/core@7.29.0) - ember-modifier-manager-polyfill: 1.2.0(@babel/core@7.29.0) - ember-source: 6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0) - transitivePeerDependencies: - - '@babel/core' - - supports-color - '@ember/render-modifiers@3.0.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))': dependencies: '@babel/core': 7.29.0 @@ -11149,20 +10423,6 @@ snapshots: - '@babel/core' - supports-color - '@embroider/macros@1.20.2(@babel/core@7.29.0)': - dependencies: - '@embroider/shared-internals': 3.0.2 - assert-never: 1.4.0 - babel-import-util: 3.0.1 - ember-cli-babel: 8.3.1(@babel/core@7.29.0) - find-up: 5.0.0 - lodash: 4.17.23 - resolve: 1.22.11 - semver: 7.7.4 - transitivePeerDependencies: - - '@babel/core' - - supports-color - '@embroider/reverse-exports@0.2.0': dependencies: mem: 8.1.1 @@ -11203,39 +10463,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@embroider/shared-internals@3.0.2': - dependencies: - babel-import-util: 3.0.1 - debug: 4.4.3(supports-color@8.1.1) - ember-rfc176-data: 0.3.18 - fs-extra: 9.1.0 - is-subdir: 1.2.0 - js-string-escape: 1.0.1 - lodash: 4.17.23 - minimatch: 3.1.5 - pkg-entry-points: 1.1.1 - resolve-package-path: 4.0.3 - resolve.exports: 2.0.3 - semver: 7.7.4 - typescript-memoize: 1.1.1 - transitivePeerDependencies: - - supports-color - '@embroider/test-setup@4.0.0': dependencies: lodash: 4.17.21 resolve: 1.22.11 - '@embroider/util@1.13.5(@babel/core@7.29.0)(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))': - dependencies: - '@embroider/macros': 1.19.5(@babel/core@7.29.0) - broccoli-funnel: 3.0.8 - ember-cli-babel: 8.2.0(@babel/core@7.29.0) - ember-source: 6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0) - transitivePeerDependencies: - - '@babel/core' - - supports-color - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.4(jiti@2.6.1))': dependencies: eslint: 9.39.4(jiti@2.6.1) @@ -12739,14 +11971,6 @@ snapshots: reselect: 4.1.8 resolve: 1.22.11 - babel-plugin-module-resolver@5.0.3: - dependencies: - find-babel-config: 2.1.2 - glob: 9.3.5 - pkg-up: 3.1.0 - reselect: 4.1.8 - resolve: 1.22.11 - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): dependencies: '@babel/compat-data': 7.28.5 @@ -12765,15 +11989,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): - dependencies: - '@babel/compat-data': 7.29.0 - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5): dependencies: '@babel/core': 7.28.5 @@ -12790,14 +12005,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) - core-js-compat: 3.49.0 - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5): dependencies: '@babel/core': 7.28.5 @@ -12812,13 +12019,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color - babel-plugin-syntax-dynamic-import@6.18.0: {} babel-register@6.26.0: @@ -14023,10 +13223,6 @@ snapshots: dependencies: browserslist: 4.28.0 - core-js-compat@3.49.0: - dependencies: - browserslist: 4.28.1 - core-js@2.6.12: optional: true @@ -14252,13 +13448,6 @@ snapshots: transitivePeerDependencies: - '@babel/core' - decorator-transforms@2.3.1(@babel/core@7.29.0): - dependencies: - '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) - babel-import-util: 3.0.1 - transitivePeerDependencies: - - '@babel/core' - deep-eql@0.1.3: dependencies: type-detect: 0.1.1 @@ -14614,39 +13803,6 @@ snapshots: transitivePeerDependencies: - supports-color - ember-cli-babel@8.3.1(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) - '@babel/preset-env': 7.29.2(@babel/core@7.29.0) - '@babel/runtime': 7.12.18 - amd-name-resolver: 1.3.1 - babel-plugin-debug-macros: 0.3.4(@babel/core@7.29.0) - babel-plugin-ember-data-packages-polyfill: 0.1.2 - babel-plugin-ember-modules-api-polyfill: 3.5.0 - babel-plugin-module-resolver: 5.0.3 - broccoli-babel-transpiler: 8.0.2(@babel/core@7.29.0) - broccoli-debug: 0.6.5 - broccoli-funnel: 3.0.8 - broccoli-source: 3.0.1 - calculate-cache-key-for-tree: 2.0.0 - clone: 2.1.2 - ember-cli-babel-plugin-helpers: 1.1.1 - ember-cli-version-checker: 5.1.2 - ensure-posix-path: 1.1.1 - resolve-package-path: 4.0.3 - semver: 7.7.4 - transitivePeerDependencies: - - supports-color - ember-cli-blueprint-test-helpers@0.19.2: dependencies: chai: 4.5.0 @@ -15149,25 +14305,6 @@ snapshots: dependencies: ember-source: 6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0) - ember-modal-dialog@5.0.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))(ember-tether@3.1.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))(webpack@5.103.0))(liquid-fire@0.37.1(@babel/core@7.29.0)(velocity-animate@1.5.2))(velocity-animate@1.5.2): - dependencies: - '@babel/core': 7.29.0 - '@embroider/macros': 1.19.5(@babel/core@7.29.0) - '@embroider/util': 1.13.5(@babel/core@7.29.0)(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0)) - ember-cli-babel: 8.2.0(@babel/core@7.29.0) - ember-cli-htmlbars: 6.3.0 - ember-cli-version-checker: 5.1.2 - ember-wormhole: 0.6.1(@babel/core@7.29.0) - liquid-fire: 0.37.1(@babel/core@7.29.0)(velocity-animate@1.5.2) - velocity-animate: 1.5.2 - optionalDependencies: - ember-tether: 3.1.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))(webpack@5.103.0) - transitivePeerDependencies: - - '@glint/environment-ember-loose' - - '@glint/template' - - ember-source - - supports-color - ember-modifier-manager-polyfill@1.2.0(@babel/core@7.29.0): dependencies: ember-cli-babel: 8.2.0(@babel/core@7.29.0) @@ -15187,14 +14324,6 @@ snapshots: - '@babel/core' - supports-color - ember-modifier@4.3.0(@babel/core@7.29.0): - dependencies: - '@embroider/addon-shim': 1.10.2 - decorator-transforms: 2.3.1(@babel/core@7.29.0) - transitivePeerDependencies: - - '@babel/core' - - supports-color - ember-qunit@9.0.4(@babel/core@7.29.0)(@ember/test-helpers@4.0.5(@babel/core@7.29.0)(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0)))(qunit@2.24.2): dependencies: '@ember/test-helpers': 4.0.5(@babel/core@7.29.0)(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0)) @@ -15382,20 +14511,6 @@ snapshots: - '@babel/core' - supports-color - ember-tether@3.1.0(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0))(webpack@5.103.0): - dependencies: - '@babel/core': 7.29.0 - '@ember/render-modifiers': 2.1.0(@babel/core@7.29.0)(ember-source@6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0)) - ember-auto-import: 2.12.0(webpack@5.103.0) - ember-cli-babel: 8.2.0(@babel/core@7.29.0) - ember-cli-htmlbars: 6.3.0 - ember-source: 6.2.0(@glimmer/component@1.1.2(@babel/core@7.29.0))(rsvp@4.8.5)(webpack@5.103.0) - tether: 2.0.0 - transitivePeerDependencies: - - '@glint/template' - - supports-color - - webpack - ember-truth-helpers@5.0.0: dependencies: '@embroider/addon-shim': 1.10.2 @@ -15429,14 +14544,6 @@ snapshots: - encoding - supports-color - ember-wormhole@0.6.1(@babel/core@7.29.0): - dependencies: - ember-cli-babel: 8.2.0(@babel/core@7.29.0) - ember-cli-htmlbars: 6.3.0 - transitivePeerDependencies: - - '@babel/core' - - supports-color - emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -17490,17 +16597,6 @@ snapshots: dependencies: uc.micro: 1.0.6 - liquid-fire@0.37.1(@babel/core@7.29.0)(velocity-animate@1.5.2): - dependencies: - '@embroider/addon-shim': 1.10.2 - '@embroider/macros': 1.20.2(@babel/core@7.29.0) - ember-modifier: 4.3.0(@babel/core@7.29.0) - velocity-animate: 1.5.2 - transitivePeerDependencies: - - '@babel/core' - - '@glint/template' - - supports-color - livereload-js@3.4.1: {} loader-runner@4.3.1: {} @@ -17582,7 +16678,8 @@ snapshots: lodash@4.17.21: {} - lodash@4.17.23: {} + lodash@4.17.23: + optional: true log-symbols@2.2.0: dependencies: @@ -20130,8 +19227,6 @@ snapshots: - walrus - whiskers - tether@2.0.0: {} - textextensions@2.6.0: {} thenify-all@1.6.0: @@ -20508,8 +19603,6 @@ snapshots: vary@1.1.2: {} - velocity-animate@1.5.2: {} - w3c-hr-time@1.0.2: dependencies: browser-process-hrtime: 1.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ad7b9fc64..e7491f881 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,4 +3,3 @@ packages: onlyBuiltDependencies: - '@parcel/watcher' - - ember-modal-dialog diff --git a/tests/acceptance/keyboard-shortcuts-test.js b/tests/acceptance/keyboard-shortcuts-test.js new file mode 100644 index 000000000..48344416c --- /dev/null +++ b/tests/acceptance/keyboard-shortcuts-test.js @@ -0,0 +1,120 @@ +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import { setupMockVersions } from '../helpers/mock-versions'; +import { click, triggerEvent, visit, waitUntil } from '@ember/test-helpers'; + +const DIALOG = '[data-test-docs-keyboard-shortcuts-dialog]'; + +function pressQuestionMark() { + return triggerEvent(document.body, 'keyup', { + key: '?', + code: 'Slash', + shiftKey: true, + }); +} + +module('Acceptance | Keyboard shortcuts dialog', function (hooks) { + setupApplicationTest(hooks); + setupMockVersions(hooks); + + test('pressing ? opens the shortcuts as a native modal dialog', async function (assert) { + await visit('/'); + assert.dom(DIALOG).doesNotExist(); + + await pressQuestionMark(); + + let dialog = document.querySelector(DIALOG); + assert.dom(dialog).exists().hasAttribute('open'); + assert.ok(dialog.matches(':modal'), 'the dialog is shown with showModal()'); + assert.strictEqual( + document.activeElement, + dialog, + 'focus moves into the dialog', + ); + assert.dom(dialog).includesText('Keyboard shortcuts'); + + await pressQuestionMark(); + assert.dom(DIALOG).doesNotExist('pressing ? again closes it'); + }); + + test('it keeps the layout of the previous modal', async function (assert) { + await visit('/'); + await pressQuestionMark(); + + let dialog = document.querySelector(DIALOG); + let rect = dialog.getBoundingClientRect(); + + assert.closeTo(rect.width, 600, 1, 'the dialog is 600px wide'); + assert.closeTo(rect.top, 100, 1, 'the dialog sits 100px from the top'); + assert.closeTo( + rect.left + rect.width / 2, + window.innerWidth / 2, + 1, + 'the dialog is horizontally centered', + ); + assert.strictEqual( + getComputedStyle(dialog, '::backdrop').backgroundColor, + 'rgba(27, 31, 35, 0.5)', + 'the backdrop is the same translucent overlay as before', + ); + assert.strictEqual( + getComputedStyle(document.body).overflow, + 'hidden', + 'the page behind the dialog does not scroll', + ); + }); + + test('the close button closes it', async function (assert) { + await visit('/'); + await pressQuestionMark(); + assert.dom(DIALOG).exists(); + + await click('[data-test-docs-keyboard-shortcuts-close]'); + assert.dom(DIALOG).doesNotExist(); + }); + + test('clicking the backdrop closes it', async function (assert) { + await visit('/'); + await pressQuestionMark(); + assert.dom(DIALOG).exists(); + + // A click whose target is the itself lands on its ::backdrop + await click(DIALOG); + assert.dom(DIALOG).doesNotExist(); + }); + + test('clicking inside the dialog keeps it open', async function (assert) { + await visit('/'); + await pressQuestionMark(); + + await click(`${DIALOG} .docs-fullscreen-modal__body`); + assert.dom(DIALOG).exists(); + }); + + test('Escape closes it', async function (assert) { + await visit('/'); + await pressQuestionMark(); + assert.dom(DIALOG).exists(); + + await triggerEvent(document.body, 'keyup', { + key: 'Escape', + code: 'Escape', + }); + assert.dom(DIALOG).doesNotExist(); + }); + + test('closing the dialog natively keeps the component state in sync', async function (assert) { + await visit('/'); + await pressQuestionMark(); + + // This is what the browser does itself on Escape or a light-dismiss click. + // The `close` event is dispatched asynchronously, so wait for it. + document.querySelector(DIALOG).close(); + await waitUntil(() => !document.querySelector(DIALOG)); + + assert.dom(DIALOG).doesNotExist(); + + await pressQuestionMark(); + assert.dom(DIALOG).exists('it can be reopened afterwards'); + }); +}); diff --git a/tests/acceptance/search-test.js b/tests/acceptance/search-test.js index 803594616..205982976 100644 --- a/tests/acceptance/search-test.js +++ b/tests/acceptance/search-test.js @@ -1,7 +1,18 @@ import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; import { setupMockVersions } from '../helpers/mock-versions'; -import { click, currentURL, fillIn, visit, waitFor } from '@ember/test-helpers'; +import { + click, + currentURL, + fillIn, + triggerEvent, + visit, + waitFor, +} from '@ember/test-helpers'; + +const INPUT = '[data-test-search-box-input]'; +const POPOVER = '[data-test-docs-search-results]'; +const RESULTS = '[data-test-search-result-list]'; module('Acceptance | Search', function (hooks) { setupApplicationTest(hooks); @@ -26,4 +37,73 @@ module('Acceptance | Search', function (hooks) { await click('[data-test-search-result] a'); assert.strictEqual(currentURL(), '/docs/api/components/docs-hero'); }); + + module('results popover', function (hooks) { + hooks.beforeEach(async function () { + await visit('/'); + await fillIn(INPUT, 'quickstart'); + await waitFor('[data-test-search-result]', { timeout: 2000 }); + }); + + test('it renders in the top layer, aligned under the search box', async function (assert) { + let list = document.querySelector(RESULTS); + assert.ok( + document.querySelector(POPOVER).matches(':popover-open'), + 'the results are shown in an open popover', + ); + + let listRect = list.getBoundingClientRect(); + let boxRect = document + .querySelector('[data-search-box]') + .getBoundingClientRect(); + + // Left edges line up, unless that would push the list past the right + // edge of the viewport, in which case it hugs the viewport edge instead + let expectedLeft = Math.min( + boxRect.left, + window.innerWidth - listRect.width, + ); + assert.closeTo(listRect.left, expectedLeft, 1, 'left edges line up'); + assert.closeTo( + listRect.top, + boxRect.bottom, + 1, + 'the list starts right below the search box', + ); + assert.closeTo(listRect.width, 304, 1, 'the list keeps its 19rem width'); + assert.ok( + listRect.right <= window.innerWidth, + 'the list stays inside the viewport', + ); + }); + + test('clicking outside closes the results and clears the query', async function (assert) { + await triggerEvent(document.body, 'pointerdown'); + + assert.dom(RESULTS).doesNotExist(); + assert.dom(INPUT).hasValue(''); + }); + + test('clicking the search box keeps the results open', async function (assert) { + await triggerEvent(INPUT, 'pointerdown'); + await click(INPUT); + + assert.dom(RESULTS).exists(); + assert.dom(INPUT).hasValue('quickstart'); + }); + + test('clicking a result keeps it open until navigation', async function (assert) { + await triggerEvent('[data-test-search-result]', 'pointerdown'); + assert.dom(RESULTS).exists(); + }); + + test('Escape closes the results', async function (assert) { + await triggerEvent(document.body, 'keydown', { + key: 'Escape', + code: 'Escape', + }); + + assert.dom(RESULTS).doesNotExist(); + }); + }); }); diff --git a/tests/acceptance/version-selector-test.js b/tests/acceptance/version-selector-test.js index 800dc0369..1b6f725bd 100644 --- a/tests/acceptance/version-selector-test.js +++ b/tests/acceptance/version-selector-test.js @@ -4,7 +4,10 @@ import { setupMockVersions, mockVersionsEndpoint, } from '../helpers/mock-versions'; -import { visit, click } from '@ember/test-helpers'; +import { visit, click, triggerEvent } from '@ember/test-helpers'; + +const TRIGGER = '[data-test-id="current-version"]'; +const LIST = '[data-test-docs-version-selector]'; let config; @@ -151,6 +154,88 @@ module('Acceptance | Version selector test', function (hooks) { .includesText('main', 'main is rendered on second open'); }); + module('popover behaviour', function (hooks) { + hooks.beforeEach(async function () { + await visit('/'); + await click(TRIGGER); + }); + + test('it opens in the top layer, right-aligned below the trigger', async function (assert) { + let list = document.querySelector(LIST); + assert.ok(list.matches(':popover-open'), 'the list is an open popover'); + + let listRect = list.getBoundingClientRect(); + let triggerRect = document.querySelector(TRIGGER).getBoundingClientRect(); + + assert.closeTo( + listRect.right, + triggerRect.right, + 1, + 'right edges line up', + ); + assert.closeTo( + listRect.top, + triggerRect.bottom + 8, + 1, + 'the list sits 0.5rem below the trigger', + ); + }); + + test('clicking the trigger again closes it', async function (assert) { + await click(TRIGGER); + assert.dom(LIST).doesNotExist(); + }); + + test('clicking outside closes it', async function (assert) { + await triggerEvent(document.body, 'pointerdown'); + assert.dom(LIST).doesNotExist(); + }); + + test('clicking inside keeps it open', async function (assert) { + await triggerEvent(`${LIST} li:nth-child(2) a`, 'pointerdown'); + assert.dom(LIST).exists(); + }); + + test('Escape closes it', async function (assert) { + await triggerEvent(document.body, 'keydown', { + key: 'Escape', + code: 'Escape', + }); + assert.dom(LIST).doesNotExist(); + }); + }); + + test('a long list of versions scrolls instead of running off the viewport', async function (assert) { + let versions = {}; + for (let i = 0; i < 60; i++) { + let name = `v0.${String(99 - i).padStart(2, '0')}.0`; + versions[name] = { + sha: String(i).padStart(40, '0'), + tag: name, + path: name, + name, + }; + } + mockVersionsEndpoint(this.server, versions); + + await visit('/'); + await click(TRIGGER); + + let list = document.querySelector(LIST); + let rect = list.getBoundingClientRect(); + + assert.dom('[data-test-id="version"]').exists({ count: 60 }); + assert.ok( + rect.bottom <= window.innerHeight, + `the list ends inside the viewport (${rect.bottom} <= ${window.innerHeight})`, + ); + let scroller = list.querySelector('ul'); + assert.ok( + scroller.scrollHeight > scroller.clientHeight, + 'the list scrolls internally', + ); + }); + module('with a custom primary branch configured', function (hooks) { let oldPrimaryBranch; hooks.beforeEach(function () { diff --git a/tests/dummy/config/environment.js b/tests/dummy/config/environment.js index f7ee8e88b..df703b797 100644 --- a/tests/dummy/config/environment.js +++ b/tests/dummy/config/environment.js @@ -39,10 +39,6 @@ module.exports = function (environment) { ENV.APP.rootElement = '#ember-testing'; ENV.APP.autoboot = false; - - ENV['ember-tether'] = { - bodyElementId: 'ember-testing', - }; } if (environment === 'production') { diff --git a/tests/integration/modifiers/docs-dialog-test.js b/tests/integration/modifiers/docs-dialog-test.js new file mode 100644 index 000000000..349dce295 --- /dev/null +++ b/tests/integration/modifiers/docs-dialog-test.js @@ -0,0 +1,94 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, settled, waitUntil } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Modifier | docs-dialog', function (hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function () { + this.set('onClose', () => {}); + this.set('isOpen', true); + }); + + test('it opens the dialog as a modal and focuses it', async function (assert) { + await render(hbs` + {{#if this.isOpen}} + + + + {{/if}} + `); + + let dialog = document.querySelector('[data-dialog]'); + assert.true(dialog.open, 'the dialog is open'); + assert.ok(dialog.matches(':modal'), 'the dialog is modal'); + assert.strictEqual(document.activeElement, dialog, 'the dialog has focus'); + + this.set('isOpen', false); + assert.dom('[data-dialog]').doesNotExist(); + }); + + test('it calls onClose when the dialog closes natively', async function (assert) { + let closes = 0; + this.set('onClose', () => closes++); + + await render(hbs` + + + + `); + + document.querySelector('[data-dialog]').close(); + await waitUntil(() => closes === 1); + assert.strictEqual(closes, 1, 'onClose was called once'); + }); + + test('it calls onClose for a backdrop click but not for a click inside', async function (assert) { + let closes = 0; + this.set('onClose', () => closes++); + + await render(hbs` + + + + `); + + await click('[data-inside]'); + assert.strictEqual(closes, 0, 'a click inside does not close'); + + // A click dispatched on the element itself is what a backdrop + // click looks like: the target is the dialog, not one of its children. + await click('[data-dialog]'); + assert.strictEqual(closes, 1, 'a backdrop click closes'); + }); + + test('it swaps the onClose callback without reopening the dialog', async function (assert) { + let firstCloses = 0; + let secondCloses = 0; + this.set('onClose', () => firstCloses++); + + await render(hbs` + + + + `); + + let dialog = document.querySelector('[data-dialog]'); + let showModalCalls = 0; + let originalShowModal = dialog.showModal; + dialog.showModal = function () { + showModalCalls++; + return originalShowModal.call(this); + }; + + this.set('onClose', () => secondCloses++); + await settled(); + await click('[data-dialog]'); + + assert.strictEqual(showModalCalls, 0, 'showModal was not called again'); + assert.true(dialog.open, 'the dialog stayed open'); + assert.strictEqual(firstCloses, 0, 'the old callback was detached'); + assert.strictEqual(secondCloses, 1, 'the new callback is used'); + }); +}); diff --git a/tests/integration/modifiers/docs-popover-test.js b/tests/integration/modifiers/docs-popover-test.js new file mode 100644 index 000000000..a5038eac8 --- /dev/null +++ b/tests/integration/modifiers/docs-popover-test.js @@ -0,0 +1,148 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, settled, triggerEvent } from '@ember/test-helpers'; +import { supportsAnchorPositioning } from 'ember-cli-addon-docs/-private/popover'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Modifier | docs-popover', function (hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function () { + this.set('onClose', () => {}); + this.set('isOpen', true); + }); + + test('it shows the element as a popover while rendered', async function (assert) { + await render(hbs` + + {{#if this.isOpen}} +
      +
    • Item
    • +
    + {{/if}} + `); + + assert.dom('[data-popover]').isVisible(); + assert.ok( + document.querySelector('[data-popover]').matches(':popover-open'), + 'the element is open as a popover', + ); + assert.strictEqual( + document.querySelector('[data-popover]').dataset.docsPlacement, + 'bottom-start', + 'placement defaults to bottom-start', + ); + + this.set('isOpen', false); + assert.dom('[data-popover]').doesNotExist(); + }); + + test('it calls onClose on outside pointerdown and Escape, but not on the anchor or trigger', async function (assert) { + let closes = 0; + this.set('onClose', () => closes++); + + await render(hbs` + + + +
      +
    • Item
    • +
    + `); + + assert.strictEqual( + document.querySelector('[data-popover]').dataset.docsPlacement, + 'bottom-end', + ); + + await triggerEvent('[data-inside]', 'pointerdown'); + await triggerEvent('[data-anchor]', 'pointerdown'); + await triggerEvent('[data-trigger]', 'pointerdown'); + assert.strictEqual(closes, 0, 'inside, anchor and trigger do not close'); + + await triggerEvent('[data-outside]', 'pointerdown'); + assert.strictEqual(closes, 1, 'outside pointerdown closes'); + + await triggerEvent(document.body, 'keydown', { key: 'Escape' }); + assert.strictEqual(closes, 2, 'Escape closes'); + }); + + test('it re-runs with the new callback when onClose changes', async function (assert) { + let firstCloses = 0; + let secondCloses = 0; + this.set('onClose', () => firstCloses++); + + await render(hbs` + +
      +
    • Item
    • +
    + `); + + this.set('onClose', () => secondCloses++); + await triggerEvent(document.body, 'pointerdown'); + + assert.strictEqual(firstCloses, 0, 'the old listener was torn down'); + assert.strictEqual(secondCloses, 1, 'the new callback is used'); + assert.ok( + document.querySelector('[data-popover]').matches(':popover-open'), + 'the popover stays open across the re-run', + ); + }); + + test('it tears down listeners and anchor styles when the element is destroyed', async function (assert) { + let closes = 0; + this.set('onClose', () => closes++); + + await render(hbs` + + {{#if this.isOpen}} +
      +
    • Item
    • +
    + {{/if}} + `); + + let anchor = document.querySelector('[data-anchor]'); + assert.ok( + !supportsAnchorPositioning() || anchor.style.anchorName, + 'the anchor is named while the popover is open', + ); + + this.set('isOpen', false); + await settled(); + + await triggerEvent(document.body, 'pointerdown'); + await triggerEvent(document.body, 'keydown', { key: 'Escape' }); + assert.strictEqual(closes, 0, 'the document listeners were removed'); + assert.notOk( + anchor.style.anchorName, + 'the anchor name assigned to the anchor was cleared', + ); + }); +});