diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index b58b603..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
diff --git a/.idea/bridget.iml b/.idea/bridget.iml
deleted file mode 100644
index 0c8867d..0000000
--- a/.idea/bridget.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 70eea87..0000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index 79ee123..0000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 03d9549..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
deleted file mode 100644
index d23208f..0000000
--- a/.idea/jsLibraryMappings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jsLinters/eslint.xml b/.idea/jsLinters/eslint.xml
deleted file mode 100644
index b269b71..0000000
--- a/.idea/jsLinters/eslint.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index a6ba3d7..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml
deleted file mode 100644
index fb0d65a..0000000
--- a/.idea/watcherTasks.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
index 4107696..263da8b 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,9 +1,18 @@
{
-"useTabs": false,
-"tabWidth": 2,
-"printWidth": 88,
-"singleQuote": true,
-"trailingComma": "none",
-"bracketSpacing": true,
-"semi": false
+ "useTabs": false,
+ "tabWidth": 2,
+ "printWidth": 88,
+ "singleQuote": true,
+ "trailingComma": "none",
+ "bracketSpacing": true,
+ "semi": false,
+ "plugins": ["prettier-plugin-go-template"],
+ "overrides": [
+ {
+ "files": ["*.html"],
+ "options": {
+ "parser": "go-template"
+ }
+ }
+ ]
}
diff --git a/assets/css/_core/_base.scss b/assets/css/_core/_base.scss
index d65d850..865a8c5 100644
--- a/assets/css/_core/_base.scss
+++ b/assets/css/_core/_base.scss
@@ -1,14 +1,20 @@
-html {
- font-family: $global-font-family;
- overflow: hidden;
- position: relative;
- scroll-behavior: smooth;
+* {
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
body {
- background-color: white;
- height: 100vh;
- margin: 0;
- overflow: hidden;
- line-height: 1.5;
-}
\ No newline at end of file
+ user-select: none;
+ background: white;
+}
+
+html,
+body {
+ overscroll-behavior-y: none;
+}
+
+a,
+button {
+ cursor: pointer;
+}
+
diff --git a/assets/css/_core/_font.scss b/assets/css/_core/_font.scss
new file mode 100644
index 0000000..397038e
--- /dev/null
+++ b/assets/css/_core/_font.scss
@@ -0,0 +1,6 @@
+@font-face {
+ font-family: HelveticaNow;
+ src: url('/fonts/HelveticaNowText-Regular.woff') format('woff');
+ font-weight: 400;
+ font-style: normal;
+}
diff --git a/assets/css/_core/_media.scss b/assets/css/_core/_media.scss
deleted file mode 100644
index e69de29..0000000
diff --git a/assets/css/_core/_mixins.scss b/assets/css/_core/_mixins.scss
new file mode 100644
index 0000000..d818128
--- /dev/null
+++ b/assets/css/_core/_mixins.scss
@@ -0,0 +1,28 @@
+$breakpoints: (
+ 'mobile': 375px,
+ 'tablet': 768px,
+ 'laptop': 1024px,
+ 'desktop': 1440px
+) !default;
+
+// Breakpoints
+
+@mixin min-width($breakpoint) {
+ @if map-has-key($breakpoints, $breakpoint) {
+ @media (min-width: map-get($breakpoints, $breakpoint)) {
+ @content;
+ }
+ } @else {
+ @error "Unfortunately, no value could be retrieved from `#{$breakpoint}`. " + "Available breakpoints are: #{map-keys($breakpoints)}.";
+ }
+}
+
+@mixin max-width($breakpoint) {
+ @if map-has-key($breakpoints, $breakpoint) {
+ @media (max-width: (map-get($breakpoints, $breakpoint) - 1px)) {
+ @content;
+ }
+ } @else {
+ @error "Unfortunately, no value could be retrieved from `#{$breakpoint}`. " + "Available breakpoints are: #{map-keys($breakpoints)}.";
+ }
+}
diff --git a/assets/css/_core/_reset.scss b/assets/css/_core/_reset.scss
new file mode 100644
index 0000000..0de3854
--- /dev/null
+++ b/assets/css/_core/_reset.scss
@@ -0,0 +1,103 @@
+/***
+ The new CSS reset - version 1.8.4 (last updated 14.2.2023)
+ GitHub page: https://github.com/elad2412/the-new-css-reset
+***/
+
+/*
+ Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property
+ - The "symbol *" part is to solve Firefox SVG sprite bug
+ */
+*:where(:not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *)) {
+ all: unset;
+ display: revert;
+}
+
+/* Preferred box-sizing value */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+/* Reapply the pointer cursor for anchor tags */
+a,
+button {
+ cursor: revert;
+}
+
+/* Remove list styles (bullets/numbers) */
+ol,
+ul,
+menu {
+ list-style: none;
+}
+
+/* For images to not be able to exceed their container */
+img {
+ max-inline-size: 100%;
+ max-block-size: 100%;
+}
+
+/* removes spacing between cells in tables */
+table {
+ border-collapse: collapse;
+}
+
+/* Safari - solving issue when using user-select:none on the
text input doesn't working */
+input,
+textarea {
+ -webkit-user-select: auto;
+}
+
+/* revert the 'white-space' property for textarea elements on Safari */
+textarea {
+ white-space: revert;
+}
+
+/* minimum style to allow to style meter element */
+meter {
+ -webkit-appearance: revert;
+ appearance: revert;
+}
+
+/* preformatted text - use only for this feature */
+:where(pre) {
+ all: revert;
+}
+
+/* reset default text opacity of input placeholder */
+::placeholder {
+ color: unset;
+}
+
+/* remove default dot (•) sign */
+::marker {
+ content: initial;
+}
+
+/* fix the feature of 'hidden' attribute.
+ display:revert; revert to element instead of attribute */
+:where([hidden]) {
+ display: none;
+}
+
+/* revert for bug in Chromium browsers
+ - fix for the content editable attribute will work properly.
+ - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/
+:where([contenteditable]:not([contenteditable='false'])) {
+ -moz-user-modify: read-write;
+ -webkit-user-modify: read-write;
+ overflow-wrap: break-word;
+ -webkit-line-break: after-white-space;
+ -webkit-user-select: auto;
+}
+
+/* apply back the draggable feature - exist only in Chromium and Safari */
+:where([draggable='true']) {
+ -webkit-user-drag: element;
+}
+
+/* Revert Modal native behavior */
+:where(dialog:modal) {
+ all: revert;
+}
diff --git a/assets/css/_core/_typography.scss b/assets/css/_core/_typography.scss
new file mode 100644
index 0000000..00d5d55
--- /dev/null
+++ b/assets/css/_core/_typography.scss
@@ -0,0 +1,14 @@
+@import 'mixins';
+
+body {
+ line-height: 1.2;
+ font-size: 16px;
+ font-family: HelveticaNow, helvetica, arial, sans-serif;
+
+ @include min-width('tablet') {
+ font-size: 18px;
+ }
+ @include min-width('laptop') {
+ font-size: 19px;
+ }
+}
diff --git a/assets/css/_partial/_customCursor.scss b/assets/css/_partial/_customCursor.scss
new file mode 100644
index 0000000..591c8f5
--- /dev/null
+++ b/assets/css/_partial/_customCursor.scss
@@ -0,0 +1,21 @@
+.cursor {
+ position: fixed;
+ z-index: var(--z-cursor);
+ top: 0;
+ left: 0;
+
+ display: none;
+ cursor: none;
+ pointer-events: none;
+
+ color: white;
+ mix-blend-mode: difference;
+}
+
+.active {
+ display: block;
+}
+
+.cursorInner {
+ transform: translate3d(-50%, -50%, 0);
+}
diff --git a/assets/css/_partial/_footer.scss b/assets/css/_partial/_footer.scss
deleted file mode 100644
index 62823fb..0000000
--- a/assets/css/_partial/_footer.scss
+++ /dev/null
@@ -1,75 +0,0 @@
-footer {
- max-height: fit-content;
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- z-index: 22;
- background-color: #fff;
- height: 38px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 20px;
- line-height: 1.5;
- padding: 4px 9px;
- float: none;
-
- .footer_name {
- }
-
- .footer_categoryWrapper {
- .footer_category {
- cursor: pointer;
- }
-
- .selected {
- text-decoration: underline;
- font-style: italic;
- }
- }
-
- .footer_threshold {
- button {
- border: none;
- background-color: transparent;
- margin: 0;
- font-size: 20px;
- padding: 0 4px;
- cursor: pointer;
- }
-
- .thid{
- display: inline-block;
- text-align: center;
- width: 48px;
- }
- }
-
- .footer_imageIndex {
- margin: 0;
-
- .ftid {
- display: inline-block;
- text-align: center;
- width: 7px;
- }
- }
-}
-
-@media only screen and (max-width: 768px) {
- footer {
- top: 0;
- padding: 3px 8px;
- font-size: 17px;
- height: 31px;
-
- .footer_threshold {
- display: none;
- }
-
- .footer_imageIndex {
- display: none;
- }
- }
-}
\ No newline at end of file
diff --git a/assets/css/_partial/_imagesDesktop.scss b/assets/css/_partial/_imagesDesktop.scss
deleted file mode 100644
index a3e3a86..0000000
--- a/assets/css/_partial/_imagesDesktop.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-.imagesDesktop {
-
- img {
- position: absolute;
- top: 0;
- left: 0;
- object-fit: contain;
- max-height: 50vmin;
- max-width: 100vw;
-
- &[data-status='null'] {
- opacity: 1;
- }
-
- &[data-status='top'] {
- opacity: 1;
- max-height: calc(100vh - var(--footer-height));;
- transition-property: transform, max-height;
- transition-timing-function: ease-in-out;
- transition-duration: 0.5s, 0.5s;
- }
-
- &[data-status='trail'] {
- opacity: 0;
- margin-top: 40px;
- transition-property: opacity, margin-top;
- transition-timing-function: ease-out;
- transition-duration: 0.2s;
- }
-
- &[data-status='resumeTop'] {
- opacity: 1;
- max-height: 50vmin;
- transition-property: max-height, transform;
- transition-timing-function: ease-in-out;
- transition-duration: 0.7s, 0.5s;
- }
-
- &[data-status='resume'] {
- opacity: 1;
- margin-top: 0;
- transition-property: opacity, margin-top;
- transition-timing-function: ease-out;
- transition-duration: 0.2s;
- }
-
- &[data-status='overlay'] {
- opacity: 1;
- max-height: calc(100vh - var(--footer-height));
- }
- }
-}
\ No newline at end of file
diff --git a/assets/css/_partial/_imagesMobile.scss b/assets/css/_partial/_imagesMobile.scss
deleted file mode 100644
index ea94e08..0000000
--- a/assets/css/_partial/_imagesMobile.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-.imagesMobile {
- height: 100vh;
- overflow: scroll;
- position: relative;
-
- img {
- height: 20vh;
- width: 60vw;
- object-fit: contain;
- position: sticky;
- top: 50vh;
- margin-left: 0;
- margin-right: 0;
- margin-bottom: 20vh;
- }
-}
\ No newline at end of file
diff --git a/assets/css/_partial/_nav.scss b/assets/css/_partial/_nav.scss
new file mode 100644
index 0000000..6b4d1c3
--- /dev/null
+++ b/assets/css/_partial/_nav.scss
@@ -0,0 +1,44 @@
+@import '../_core/mixins';
+$tablet: map-get($breakpoints, 'tablet') - 1;
+
+nav {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ width: 100%;
+ height: var(--nav-height);
+ padding: 0 var(--space-standard);
+
+ position: fixed;
+ bottom: 0;
+ background: white;
+
+ z-index: var(--z-nav);
+
+ // Maintain functionality while container is locked
+ pointer-events: all;
+}
+
+.num {
+ width: 0.625em;
+ display: inline-block;
+ text-align: center;
+}
+
+.current {
+ font-style: italic;
+ text-decoration: underline;
+}
+
+@media (max-width: $tablet), (hover: none) {
+ nav {
+ top: 0;
+ position: sticky;
+ }
+
+ .index,
+ .threshold {
+ display: none;
+ }
+}
diff --git a/assets/css/_partial/_overlay.scss b/assets/css/_partial/_overlay.scss
deleted file mode 100644
index 9c55b08..0000000
--- a/assets/css/_partial/_overlay.scss
+++ /dev/null
@@ -1,15 +0,0 @@
-.overlay_cursor {
- position: fixed;
- top: 0;
- left: 0;
- mix-blend-mode: difference;
- font-size: 19px;
- box-sizing: border-box;
- cursor: none;
- user-select: none;
-
- .cursor_innerText {
- color: white;
- transform: translate3d(-50%, -50%, 0);
- }
-}
\ No newline at end of file
diff --git a/assets/css/_partial/_stage.scss b/assets/css/_partial/_stage.scss
new file mode 100644
index 0000000..ef53850
--- /dev/null
+++ b/assets/css/_partial/_stage.scss
@@ -0,0 +1,22 @@
+.stage {
+ position: relative;
+ overflow: hidden;
+ width: 100vw;
+ height: calc(var(--window-height) - var(--nav-height));
+
+ cursor: pointer;
+
+ img {
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ width: 100vw;
+ height: var(--window-height);
+ object-fit: contain;
+
+ transform: scale(0.6);
+ opacity: 0;
+ pointer-events: none;
+ }
+}
diff --git a/assets/css/_partial/_stageNav.scss b/assets/css/_partial/_stageNav.scss
new file mode 100644
index 0000000..c347049
--- /dev/null
+++ b/assets/css/_partial/_stageNav.scss
@@ -0,0 +1,21 @@
+.navOverlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: var(--z-nav-gallery);
+
+ width: 100vw;
+ height: calc(var(--window-height) - var(--nav-height));
+
+ display: flex;
+ cursor: none;
+
+ &:not(.active) {
+ pointer-events: none;
+ display: none;
+ }
+
+ .overlay {
+ flex: 1;
+ }
+}
diff --git a/assets/css/_variables.scss b/assets/css/_variables.scss
index 193d082..b126326 100644
--- a/assets/css/_variables.scss
+++ b/assets/css/_variables.scss
@@ -1,14 +1,12 @@
-// ==============================
-// Variables
-// ==============================
-
-// ========== Global ========== //
-// Font and Line Height
-$global-font-family: system-ui, -apple-system, BlinkMacSystemFont, PingFang SC, Microsoft YaHei UI, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, Helvetica, Arial, sans-serif !default;
-$global-font-size: 16px;
-$global-font-weight: 400;
-$global-line-height: 1.5rem;
+@import '_core/mixins';
:root {
- --footer-height: 38px;
-}
\ No newline at end of file
+ --window-height: 100vh;
+ --nav-height: 2rem;
+ --space-standard: 0.625rem;
+
+ --z-curtain: 200;
+ --z-nav-gallery: 500;
+ --z-cursor: 600;
+ --z-nav: 800;
+}
diff --git a/assets/css/style.scss b/assets/css/style.scss
index 7df3db5..96c8842 100644
--- a/assets/css/style.scss
+++ b/assets/css/style.scss
@@ -1,15 +1,13 @@
@charset "utf-8";
-@import "_variables";
+@import '_core/reset';
+@import '_core/font';
+@import '_core/typography';
+@import '_core/mixins';
+@import '_variables';
+@import '_core/base';
-@import "_core/base";
-
-@import "_core/media";
-
-@import "_partial/imagesDesktop";
-
-@import "_partial/imagesMobile";
-
-@import "_partial/footer";
-
-@import "_partial/overlay";
\ No newline at end of file
+@import '_partial/customCursor';
+@import '_partial/nav';
+@import '_partial/stage';
+@import '_partial/stageNav';
diff --git a/assets/ts/customCursor.ts b/assets/ts/customCursor.ts
new file mode 100644
index 0000000..030e1a2
--- /dev/null
+++ b/assets/ts/customCursor.ts
@@ -0,0 +1,38 @@
+import { active } from './stage'
+
+let cursor: HTMLDivElement
+
+// create cursor
+cursor = document.createElement('div')
+cursor.className = 'cursor'
+cursor.classList.add('active')
+// create cursor inner
+const cursorInner = document.createElement('div')
+cursorInner.className = 'cursorInner'
+// append cursor inner to cursor
+cursor.append(cursorInner)
+
+function onMouse(e: MouseEvent) {
+ const x = e.clientX
+ const y = e.clientY
+ cursor.style.transform = `translate3d(${x}px, ${y}px, 0)`
+}
+
+export function initCustomCursor(): void {
+ // append cursor to main
+ document.getElementById('main')!.append(cursor)
+ // bind mousemove event to window
+ window.addEventListener('mousemove', onMouse)
+ // add active callback
+ active.addWatcher(() => {
+ if (active.get()) {
+ cursor.classList.add('active')
+ } else {
+ cursor.classList.remove('active')
+ }
+ })
+}
+
+export function setCustomCursor(text: string): void {
+ cursorInner.innerText = text
+}
diff --git a/assets/ts/dataFetch.ts b/assets/ts/dataFetch.ts
deleted file mode 100644
index 07db65d..0000000
--- a/assets/ts/dataFetch.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { type ImageData } from './utils'
-
-// fetch images info from JSON
-const imageArrayElement = document.getElementById('images_array') as HTMLScriptElement
-const rawImageArray = imageArrayElement.textContent as string
-export const imagesArray: ImageData[] = JSON.parse(rawImageArray).sort(
- (a: ImageData, b: ImageData) => {
- if (a.index < b.index) {
- return -1
- }
- return 1
- }
-)
-export const imagesArrayLen: number = imagesArray.length
diff --git a/assets/ts/desktop.ts b/assets/ts/desktop.ts
deleted file mode 100644
index dba830e..0000000
--- a/assets/ts/desktop.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import { overlayEnable } from './overlay'
-import {
- calcImageIndex,
- center,
- delay,
- mouseToTransform,
- pushIndex,
- type position,
- hideImage
-} from './utils'
-import { thresholdIndex, thresholdSensitivityArray } from './thresholdCtl'
-import { imgIndexSpanUpdate } from './indexDisp'
-import { imagesArrayLen } from './dataFetch'
-import { imagesDivNodes as images } from './elemGen'
-
-// global index for "activated"
-export let globalIndex: number = 0
-// last position set as "activated"
-let last: position = { x: 0, y: 0 }
-export let trailingImageIndexes: number[] = []
-// only used in overlay disable, for storing positions temporarily
-export let transformCache: string[] = []
-// abort controller for enter overlay event listener
-let EnterOverlayClickAbCtl = new AbortController()
-// stack depth of images array
-export let stackDepth: number = 5
-export let lastStackDepth: number = 5
-
-export const addEnterOverlayEL = (e: HTMLImageElement): void => {
- EnterOverlayClickAbCtl.abort()
- EnterOverlayClickAbCtl = new AbortController()
- e.addEventListener(
- 'click',
- () => {
- void enterOverlay()
- },
- {
- passive: true,
- once: true,
- signal: EnterOverlayClickAbCtl.signal
- }
- )
-}
-
-// activate top image
-const activate = (index: number, mouseX: number, mouseY: number): void => {
- addEnterOverlayEL(images[index])
- if (stackDepth !== lastStackDepth) {
- trailingImageIndexes.push(index)
- refreshStack()
- lastStackDepth = stackDepth
- }
- const indexesNum: number = pushIndex(
- index,
- trailingImageIndexes,
- stackDepth,
- images,
- imagesArrayLen
- )
- // set img position
- images[index].style.transform = mouseToTransform(mouseX, mouseY, true, true)
- images[index].dataset.status = 'null'
- // reset z index
- for (let i = indexesNum; i > 0; i--) {
- images[trailingImageIndexes[i - 1]].style.zIndex = `${i}`
- }
- images[index].style.visibility = 'visible'
- last = { x: mouseX, y: mouseY }
-}
-
-// Compare the current mouse position with the last activated position
-const distanceFromLast = (x: number, y: number): number => {
- return Math.hypot(x - last.x, y - last.y)
-}
-
-// handle mouse move
-export const handleOnMove = (e: MouseEvent): void => {
- // meet threshold
- if (
- distanceFromLast(e.clientX, e.clientY) >
- window.innerWidth / thresholdSensitivityArray[thresholdIndex]
- ) {
- // calculate the actual index
- const imageIndex = calcImageIndex(globalIndex, imagesArrayLen)
- // show top image and change index
- activate(imageIndex, e.clientX, e.clientY)
- imgIndexSpanUpdate(imageIndex + 1, imagesArrayLen)
- // self increment
- globalIndexInc()
- }
-}
-
-async function enterOverlay(): Promise {
- // stop images animation
- window.removeEventListener('mousemove', handleOnMove)
- // get index array length
- const indexesNum: number = trailingImageIndexes.length
- for (let i = 0; i < indexesNum; i++) {
- // create image element
- const e: HTMLImageElement = images[trailingImageIndexes[i]]
- // cache images' position
- transformCache.push(e.style.transform)
- // set style for the images
- if (i === indexesNum - 1) {
- e.style.transitionDelay = `${0.1 * i + 0.2}s, ${0.1 * i + 0.2 + 0.5}s`
- e.dataset.status = 'top'
- center(e)
- } else {
- e.style.transitionDelay = `${0.1 * i}s`
- e.dataset.status = 'trail'
- }
- }
- // sleep
- await delay(stackDepth * 100 + 100 + 1000)
- // post process
- for (let i = 0; i < indexesNum; i++) {
- images[trailingImageIndexes[i]].style.transitionDelay = ''
- if (i === indexesNum - 1) {
- images[trailingImageIndexes[i]].dataset.status = 'overlay'
- } else {
- images[trailingImageIndexes[i]].style.visibility = 'hidden'
- }
- }
- // Offset previous self increment of global index (by handleOnMove)
- globalIndexDec()
- // overlay init
- overlayEnable()
-}
-
-// initialization
-export const trackMouseInit = (): void => {
- window.addEventListener('mousemove', handleOnMove)
-}
-
-export const globalIndexDec = (): void => {
- globalIndex--
-}
-
-export const globalIndexInc = (): void => {
- globalIndex++
-}
-
-export const emptyTransformCache = (): void => {
- transformCache = []
-}
-
-export const emptyTrailingImageIndexes = (): void => {
- trailingImageIndexes = []
-}
-
-export const setStackDepth = (newStackDepth: number): void => {
- if (stackDepth !== newStackDepth) {
- lastStackDepth = stackDepth
- stackDepth = newStackDepth
- }
-}
-
-export const refreshStack = (): void => {
- const l: number = trailingImageIndexes.length
- if (stackDepth < lastStackDepth && l > stackDepth) {
- const times: number = l - stackDepth
- for (let i = 0; i < times; i++)
- hideImage(images[trailingImageIndexes.shift() as number])
- }
-}
diff --git a/assets/ts/elemGen.ts b/assets/ts/elemGen.ts
deleted file mode 100644
index 65963f9..0000000
--- a/assets/ts/elemGen.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { imagesArray, imagesArrayLen } from './dataFetch'
-import { createImgElement } from './utils'
-
-// get components of overlay
-export let overlayCursor: HTMLDivElement
-export let cursorInnerContent: HTMLDivElement
-export let imagesDivNodes: NodeListOf
-
-const mainDiv = document.getElementById('main') as HTMLDivElement
-
-const passDesktopElements = (): void => {
- overlayCursor = document
- .getElementsByClassName('overlay_cursor')
- .item(0) as HTMLDivElement
- cursorInnerContent = document
- .getElementsByClassName('cursor_innerText')
- .item(0) as HTMLDivElement
- imagesDivNodes = document.getElementsByClassName('imagesDesktop')[0]
- .childNodes as NodeListOf
-}
-
-const passMobileElements = (): void => {
- imagesDivNodes = document.getElementsByClassName('imagesMobile')[0]
- .childNodes as NodeListOf
-}
-
-const createCursorDiv = (): HTMLDivElement => {
- const cursorDiv: HTMLDivElement = document.createElement('div')
- cursorDiv.className = 'overlay_cursor'
- const innerTextDiv: HTMLDivElement = document.createElement('div')
- innerTextDiv.className = 'cursor_innerText'
- cursorDiv.appendChild(innerTextDiv)
- return cursorDiv
-}
-
-export const createDesktopElements = (): void => {
- mainDiv.appendChild(createCursorDiv())
- const imagesDiv: HTMLDivElement = document.createElement('div')
- imagesDiv.className = 'imagesDesktop'
- for (let i = 0; i < imagesArrayLen; i++) {
- imagesDiv.appendChild(createImgElement(imagesArray[i]))
- }
- mainDiv.appendChild(imagesDiv)
- passDesktopElements()
-}
-
-export const createMobileElements = (): void => {
- const imagesDiv: HTMLDivElement = document.createElement('div')
- imagesDiv.className = 'imagesMobile'
- for (let i = 0; i < imagesArrayLen; i++) {
- imagesDiv.appendChild(createImgElement(imagesArray[i]))
- }
- mainDiv.appendChild(imagesDiv)
- passMobileElements()
-}
diff --git a/assets/ts/imageCache.ts b/assets/ts/imageCache.ts
deleted file mode 100644
index feaa88d..0000000
--- a/assets/ts/imageCache.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { imagesArray, imagesArrayLen } from './dataFetch'
-import { preloadImage, calcImageIndex } from './utils'
-
-let lastIndex: number = 0
-
-export const preloader = (index: number): void => {
- if (lastIndex === index) {
- for (let i: number = -2; i <= 1; i++)
- preloadImage(imagesArray[calcImageIndex(index + i, imagesArrayLen)].url)
- } else if (lastIndex > index) {
- for (let i: number = 1; i <= 3; i++)
- preloadImage(imagesArray[calcImageIndex(index - i, imagesArrayLen)].url)
- } else {
- for (let i: number = 1; i <= 3; i++)
- preloadImage(imagesArray[calcImageIndex(index + i, imagesArrayLen)].url)
- }
- lastIndex = index
-}
diff --git a/assets/ts/indexDisp.ts b/assets/ts/indexDisp.ts
deleted file mode 100644
index e772230..0000000
--- a/assets/ts/indexDisp.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { duper } from './utils'
-
-// update index of displaying image
-export const imgIndexSpanUpdate = (numOne: number, numTwo: number): void => {
- // footer index number display module
- const footerIndexDisp = document.getElementsByClassName('ftid')
- const numOneString: string = duper(numOne)
- const numTwoString: string = duper(numTwo)
- for (let i: number = 0; i <= 7; i++) {
- const footerIndex = footerIndexDisp[i] as HTMLSpanElement
- if (i > 3) {
- footerIndex.innerText = numTwoString[i - 4]
- } else {
- footerIndex.innerText = numOneString[i]
- }
- }
-}
diff --git a/assets/ts/main.ts b/assets/ts/main.ts
index e1e3b1b..2d58579 100644
--- a/assets/ts/main.ts
+++ b/assets/ts/main.ts
@@ -1,28 +1,13 @@
-import { createDesktopElements, createMobileElements } from './elemGen'
-import { imgIndexSpanUpdate } from './indexDisp'
-import { trackMouseInit } from './desktop'
-import { thresholdCtlInit } from './thresholdCtl'
-import { imagesArrayLen } from './dataFetch'
-import { vwRefreshInit } from './overlay'
-import { preloader } from './imageCache'
-import { getDeviceType } from './utils'
-import { renderImages } from './mobile'
+import { initResources } from './resources'
+import { initState } from './state'
+import { initCustomCursor } from './customCursor'
+import { initNav } from './nav'
+import { initStage } from './stage'
+import { initStageNav } from './stageNav'
-const desktopInit = (): void => {
- createDesktopElements()
- preloader(0)
- vwRefreshInit()
- imgIndexSpanUpdate(0, imagesArrayLen)
- thresholdCtlInit()
- trackMouseInit()
-}
-
-const mobileInit = (): void => {
- createMobileElements()
- vwRefreshInit()
- imgIndexSpanUpdate(0, imagesArrayLen)
- renderImages()
- console.log('mobile')
-}
-
-getDeviceType().desktop ? mobileInit() : desktopInit()
+initCustomCursor()
+const ijs = initResources()
+initState(ijs.length)
+initStage(ijs)
+initStageNav()
+initNav()
diff --git a/assets/ts/mobile.ts b/assets/ts/mobile.ts
deleted file mode 100644
index 8f66752..0000000
--- a/assets/ts/mobile.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { imagesDivNodes as images } from './elemGen'
-import { imagesArrayLen } from './dataFetch'
-
-export const renderImages = (): void => {
- images.forEach((img: HTMLImageElement, idx: number): void => {
- const randomX: number = Math.floor(Math.random() * 35) + 2
- let randomY: number
-
- // random Y calculation
- if (idx === 0) {
- randomY = 68
- } else if (idx === 1) {
- randomY = 44
- } else if (idx === imagesArrayLen - 1) {
- randomY = 100
- } else {
- randomY = Math.floor(Math.random() * 51) + 2
- }
-
- img.style.transform = `translate(${randomX}vw, -${randomY}%)`
- img.style.marginTop = `${idx === 1 ? 70 : 0}vh`
- img.style.visibility = 'visible'
- })
-}
diff --git a/assets/ts/nav.ts b/assets/ts/nav.ts
new file mode 100644
index 0000000..6a8b235
--- /dev/null
+++ b/assets/ts/nav.ts
@@ -0,0 +1,59 @@
+import { getState, incThreshold, decThreshold } from './state'
+import { expand } from './utils'
+
+// threshold div
+const thresholdDiv = document
+ .getElementsByClassName('threshold')
+ .item(0) as HTMLDivElement
+
+// threshold nums span
+const thresholdDispNums = Array.from(
+ thresholdDiv.getElementsByClassName('num')
+) as HTMLSpanElement[]
+
+// threshold buttons
+const decButton = thresholdDiv
+ .getElementsByClassName('dec')
+ .item(0) as HTMLButtonElement
+const incButton = thresholdDiv
+ .getElementsByClassName('inc')
+ .item(0) as HTMLButtonElement
+
+// index div
+const indexDiv = document.getElementsByClassName('index').item(0) as HTMLDivElement
+
+// index nums span
+const indexDispNums = Array.from(
+ indexDiv.getElementsByClassName('num')
+) as HTMLSpanElement[]
+
+export function initNav() {
+ // init threshold text
+ updateThresholdText()
+ // init index text
+ updateIndexText()
+ // event listeners
+ decButton.addEventListener('click', () => decThreshold())
+ incButton.addEventListener('click', () => incThreshold())
+}
+
+// helper
+
+export function updateThresholdText(): void {
+ const thresholdValue: string = expand(getState().threshold)
+ thresholdDispNums.forEach((e: HTMLSpanElement, i: number) => {
+ e.innerText = thresholdValue[i]
+ })
+}
+
+export function updateIndexText(): void {
+ const indexValue: string = expand(getState().index + 1)
+ const indexLength: string = expand(getState().length)
+ indexDispNums.forEach((e: HTMLSpanElement, i: number) => {
+ if (i < 4) {
+ e.innerText = indexValue[i]
+ } else {
+ e.innerText = indexLength[i - 4]
+ }
+ })
+}
diff --git a/assets/ts/overlay.ts b/assets/ts/overlay.ts
deleted file mode 100644
index 08e883f..0000000
--- a/assets/ts/overlay.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-import { delay, center, calcImageIndex, mouseToTransform, pushIndex } from './utils'
-import {
- handleOnMove,
- globalIndex,
- globalIndexDec,
- globalIndexInc,
- trailingImageIndexes,
- transformCache,
- emptyTransformCache,
- emptyTrailingImageIndexes,
- stackDepth,
- addEnterOverlayEL
-} from './desktop'
-import { imagesArrayLen } from './dataFetch'
-import { imgIndexSpanUpdate } from './indexDisp'
-import { overlayCursor, cursorInnerContent, imagesDivNodes as images } from './elemGen'
-
-let oneThird: number = Math.round(window.innerWidth / 3)
-
-// set cursor text
-const setCursorText = (text: string): void => {
- cursorInnerContent.innerText = text
-}
-
-// overlay cursor event handler
-const setTextPos = (e: MouseEvent): void => {
- overlayCursor.style.transform = mouseToTransform(e.clientX, e.clientY, false, true)
-}
-
-// disable listeners
-const disableListener = (): void => {
- window.removeEventListener('mousemove', handleOverlayMouseMove)
- overlayCursor.removeEventListener('click', handleOverlayClick)
-}
-
-// enable overlay
-export const overlayEnable = (): void => {
- // show the overlay components
- overlayCursor.style.zIndex = '21'
- // set overlay event listeners
- setListener()
-}
-
-// disable overlay
-export const overlayDisable = (): void => {
- // hide the overlay components
- overlayCursor.style.zIndex = '-1'
- // set overlay cursor text content to none
- setCursorText('')
- // disable overlay event listeners
- disableListener()
-}
-
-// handle close click
-async function handleCloseClick(): Promise {
- // disable overlay
- overlayDisable()
- // get length of indexes and empty indexes array
- const indexesNum = trailingImageIndexes.length
- emptyTrailingImageIndexes()
- // prepare animation
- for (let i: number = 0; i < indexesNum; i++) {
- // get element from index and store the index
- const index: number = calcImageIndex(globalIndex - i, imagesArrayLen)
- const e: HTMLImageElement = images[index]
- trailingImageIndexes.unshift(index)
- // set z index for the image element
- e.style.zIndex = `${indexesNum - i - 1}`
- // set different style for trailing and top image
- if (i === 0) {
- // set position
- e.style.transform = transformCache[indexesNum - i - 1]
- // set transition delay
- e.style.transitionDelay = '0s, 0.7s'
- // set status for css
- e.dataset.status = 'resumeTop'
- } else {
- // set position
- e.style.transform = transformCache[indexesNum - i - 1]
- // set transition delay
- e.style.transitionDelay = `${1.2 + 0.1 * i - 0.1}s`
- // set status for css
- e.dataset.status = 'resume'
- }
- // style process complete, show the image
- e.style.visibility = 'visible'
- }
- // halt the function while animation is running
- await delay(1200 + stackDepth * 100 + 100)
- // add back enter overlay event listener to top image
- addEnterOverlayEL(images[calcImageIndex(globalIndex, imagesArrayLen)])
- // clear unused status and transition delay
- for (let i: number = 0; i < indexesNum; i++) {
- const index: number = calcImageIndex(globalIndex - i, imagesArrayLen)
- images[index].dataset.status = 'null'
- images[index].style.transitionDelay = ''
- }
- // Add back previous self increment of global index (by handleOnMove)
- globalIndexInc()
- // add back mousemove event listener
- window.addEventListener('mousemove', handleOnMove, { passive: true })
- // empty the position array cache
- emptyTransformCache()
-}
-
-const handleSideClick = (CLD: boolean): void => {
- // get last displayed image's index
- const imgIndex: number = calcImageIndex(globalIndex, imagesArrayLen)
- // change global index and get current displayed image's index
- CLD ? globalIndexInc() : globalIndexDec()
- const currImgIndex: number = calcImageIndex(globalIndex, imagesArrayLen)
- // store current displayed image's index
- CLD
- ? pushIndex(
- currImgIndex,
- trailingImageIndexes,
- stackDepth,
- images,
- imagesArrayLen,
- false,
- false
- )
- : pushIndex(
- currImgIndex,
- trailingImageIndexes,
- stackDepth,
- images,
- imagesArrayLen,
- true,
- false
- )
- // hide last displayed image
- images[imgIndex].style.visibility = 'hidden'
- images[imgIndex].dataset.status = 'trail'
- // process the image going to display
- center(images[currImgIndex])
- images[currImgIndex].dataset.status = 'overlay'
- // process complete, show the image
- images[currImgIndex].style.visibility = 'visible'
- // change index display
- imgIndexSpanUpdate(currImgIndex + 1, imagesArrayLen)
-}
-
-// change text and position of overlay cursor
-const handleOverlayMouseMove = (e: MouseEvent): void => {
- // set text position
- setTextPos(e)
- // set text content
- if (e.clientX < oneThird) {
- setCursorText('PREV')
- overlayCursor.dataset.status = 'PREV'
- } else if (e.clientX < oneThird * 2) {
- setCursorText('CLOSE')
- overlayCursor.dataset.status = 'CLOSE'
- } else {
- setCursorText('NEXT')
- overlayCursor.dataset.status = 'NEXT'
- }
-}
-
-const handleOverlayClick = (): void => {
- switch (overlayCursor.dataset.status) {
- case 'PREV':
- handleSideClick(false)
- break
- case 'CLOSE':
- void handleCloseClick()
- break
- case 'NEXT':
- handleSideClick(true)
- break
- }
-}
-
-// set event listener
-const setListener = (): void => {
- // add mouse move event listener (for overlay text cursor)
- window.addEventListener('mousemove', handleOverlayMouseMove, { passive: true })
- // add close/prev/next click event listener
- overlayCursor.addEventListener('click', handleOverlayClick, { passive: true })
-}
-
-export const vwRefreshInit = (): void => {
- window.addEventListener(
- 'resize',
- () => {
- // refresh value of one third
- oneThird = Math.round(window.innerWidth / 3)
- // reset footer height
- const r = document.querySelector(':root') as HTMLStyleElement
- if (window.innerWidth > 768) {
- r.style.setProperty('--footer-height', '38px')
- } else {
- r.style.setProperty('--footer-height', '31px')
- }
- // recenter image (only in overlay)
- if (
- images[calcImageIndex(globalIndex, imagesArrayLen)].dataset.status === 'overlay'
- )
- center(images[calcImageIndex(globalIndex, imagesArrayLen)])
- },
- { passive: true }
- )
-}
diff --git a/assets/ts/resources.ts b/assets/ts/resources.ts
new file mode 100644
index 0000000..4eb0b06
--- /dev/null
+++ b/assets/ts/resources.ts
@@ -0,0 +1,21 @@
+// data structure for images info
+export interface ImageJSON {
+ index: number
+ url: string
+ imgH: number
+ imgW: number
+ pColor: string
+ sColor: string
+}
+
+export function initResources(): ImageJSON[] {
+ const imagesJson = document.getElementById('imagesSource') as HTMLScriptElement
+ return JSON.parse(imagesJson.textContent as string).sort(
+ (a: ImageJSON, b: ImageJSON) => {
+ if (a.index < b.index) {
+ return -1
+ }
+ return 1
+ }
+ )
+}
diff --git a/assets/ts/stage.ts b/assets/ts/stage.ts
new file mode 100644
index 0000000..8b22caf
--- /dev/null
+++ b/assets/ts/stage.ts
@@ -0,0 +1,184 @@
+import { incIndex, getState } from './state'
+import { gsap, Power3 } from 'gsap'
+import { ImageJSON } from './resources'
+import { Watchable } from './utils'
+
+// types
+
+export type HistoryItem = { i: number; x: number; y: number }
+
+// variables
+
+let imgs: HTMLImageElement[] = []
+let last = { x: 0, y: 0 }
+export const cordHist = new Watchable([])
+export const isOpen = new Watchable(false)
+export const isAnimating = new Watchable(false)
+export const active = new Watchable(false)
+
+// getter
+
+function getElTrail(): HTMLImageElement[] {
+ return cordHist.get().map((item) => imgs[item.i])
+}
+
+function getElTrailCurrent(): HTMLImageElement[] {
+ return getElTrail().slice(-getState().trailLength)
+}
+
+function getElTrailInactive(): HTMLImageElement[] {
+ const elTrailCurrent = getElTrailCurrent()
+ return elTrailCurrent.slice(0, elTrailCurrent.length - 1)
+}
+
+function getElCurrent(): HTMLImageElement {
+ const elTrail = getElTrail()
+ return elTrail[elTrail.length - 1]
+}
+
+// main functions
+
+// on mouse
+function onMouse(e: MouseEvent): void {
+ if (isOpen.get() || isAnimating.get()) return
+ const cord = { x: e.clientX, y: e.clientY }
+ const travelDist = Math.hypot(cord.x - last.x, cord.y - last.y)
+
+ if (travelDist > getState().threshold) {
+ last = cord
+ incIndex()
+
+ const newHist = { i: getState().index, ...cord }
+ cordHist.set([...cordHist.get(), newHist].slice(-getState().length))
+ }
+}
+
+// set image position with gsap
+function setPositions(): void {
+ const elTrail = getElTrail()
+ if (!elTrail.length) return
+
+ gsap.set(elTrail, {
+ x: (i: number) => cordHist.get()[i].x - window.innerWidth / 2,
+ y: (i: number) => cordHist.get()[i].y - window.innerHeight / 2,
+ opacity: (i: number) =>
+ i + 1 + getState().trailLength <= cordHist.get().length ? 0 : 1,
+ zIndex: (i: number) => i,
+ scale: 0.6
+ })
+
+ if (isOpen.get()) {
+ gsap.set(imgs, { opacity: 0 })
+ gsap.set(getElCurrent(), { opacity: 1, x: 0, y: 0, scale: 1 })
+ }
+}
+
+// open image into navigation
+function expandImage(): void {
+ if (isAnimating.get()) return
+
+ isOpen.set(true)
+ isAnimating.set(true)
+
+ const tl = gsap.timeline()
+ // move down and hide trail inactive
+ tl.to(getElTrailInactive(), {
+ y: '+=20',
+ ease: Power3.easeIn,
+ stagger: 0.075,
+ duration: 0.3,
+ delay: 0.1,
+ opacity: 0
+ })
+ // current move to center
+ tl.to(getElCurrent(), {
+ x: 0,
+ y: 0,
+ ease: Power3.easeInOut,
+ duration: 0.7,
+ delay: 0.3
+ })
+ // current expand
+ tl.to(getElCurrent(), {
+ delay: 0.1,
+ scale: 1,
+ ease: Power3.easeInOut
+ })
+ // finished
+ tl.then(() => {
+ isAnimating.set(false)
+ })
+}
+
+// close navigation and back to stage
+export function minimizeImage(): void {
+ if (isAnimating.get()) return
+
+ isOpen.set(false)
+ isAnimating.set(true)
+
+ const tl = gsap.timeline()
+ // shrink current
+ tl.to(getElCurrent(), {
+ scale: 0.6,
+ duration: 0.6,
+ ease: Power3.easeInOut
+ })
+ // move current to original position
+ tl.to(getElCurrent(), {
+ delay: 0.3,
+ duration: 0.7,
+ ease: Power3.easeInOut,
+ x: cordHist.get()[cordHist.get().length - 1].x - window.innerWidth / 2,
+ y: cordHist.get()[cordHist.get().length - 1].y - window.innerHeight / 2
+ })
+ // show trail inactive
+ tl.to(getElTrailInactive(), {
+ y: '-=20',
+ ease: Power3.easeOut,
+ stagger: -0.1,
+ duration: 0.3,
+ opacity: 1
+ })
+ // finished
+ tl.then(() => {
+ isAnimating.set(false)
+ })
+}
+
+// init
+
+export function initStage(ijs: ImageJSON[]): void {
+ // create stage element
+ createStage(ijs)
+ // get stage
+ const stage = document.getElementsByClassName('stage').item(0) as HTMLDivElement
+ // get image elements
+ imgs = Array.from(stage.getElementsByTagName('img'))
+ // event listeners
+ stage.addEventListener('click', () => expandImage())
+ stage.addEventListener('keydown', () => expandImage())
+ window.addEventListener('mousemove', onMouse)
+ // watchers
+ isOpen.addWatcher(() => active.set(isOpen.get() && !isAnimating.get()))
+ isAnimating.addWatcher(() => active.set(isOpen.get() && !isAnimating.get()))
+ cordHist.addWatcher(() => setPositions())
+}
+
+// hepler
+
+function createStage(ijs: ImageJSON[]): void {
+ // create container for images
+ const stage: HTMLDivElement = document.createElement('div')
+ stage.className = 'stage'
+ // append images to container
+ for (let ij of ijs) {
+ const e = document.createElement('img')
+ e.src = ij.url
+ e.height = ij.imgH
+ e.width = ij.imgW
+ e.alt = 'image'
+ stage.append(e)
+ }
+ document.getElementById('main')!.append(stage)
+}
diff --git a/assets/ts/stageNav.ts b/assets/ts/stageNav.ts
new file mode 100644
index 0000000..f37009c
--- /dev/null
+++ b/assets/ts/stageNav.ts
@@ -0,0 +1,87 @@
+import { setCustomCursor } from './customCursor'
+import { decIndex, incIndex, getState } from './state'
+import { increment, decrement } from './utils'
+import { cordHist, isOpen, isAnimating, active, minimizeImage } from './stage'
+
+type NavItem = (typeof navItems)[number]
+const navItems = ['prev', 'close', 'next'] as const
+
+// main functions
+
+function handleClick(type: NavItem) {
+ switch (type) {
+ case 'prev':
+ prevImage()
+ break
+ case 'close':
+ minimizeImage()
+ break
+ case 'next':
+ nextImage()
+ break
+ }
+}
+
+function handleKey(e: KeyboardEvent) {
+ if (isOpen.get() || isAnimating.get()) return
+ switch (e.key) {
+ case 'ArrowLeft':
+ prevImage()
+ break
+ case 'Escape':
+ minimizeImage()
+ break
+ case 'ArrowRight':
+ nextImage()
+ break
+ }
+}
+
+// init
+
+export function initStageNav() {
+ const navOverlay = document.createElement('div')
+ navOverlay.className = 'navOverlay'
+ for (let navItem of navItems) {
+ const overlay = document.createElement('div')
+ overlay.className = 'overlay'
+ overlay.addEventListener('click', () => handleClick(navItem))
+ overlay.addEventListener('keydown', () => handleClick(navItem))
+ overlay.addEventListener('mouseover', () => setCustomCursor(navItem))
+ overlay.addEventListener('focus', () => setCustomCursor(navItem))
+ navOverlay.append(overlay)
+ }
+ active.addWatcher(() => {
+ if (active.get()) {
+ navOverlay.classList.add('active')
+ } else {
+ navOverlay.classList.remove('active')
+ }
+ })
+ document.getElementById('main')!.append(navOverlay)
+ window.addEventListener('keydown', handleKey)
+}
+
+// hepler
+
+function nextImage() {
+ if (isAnimating.get()) return
+ cordHist.set(
+ cordHist.get().map((item) => {
+ return { ...item, i: increment(item.i, getState().length) }
+ })
+ )
+
+ incIndex()
+}
+
+function prevImage() {
+ if (isAnimating.get()) return
+ cordHist.set(
+ cordHist.get().map((item) => {
+ return { ...item, i: decrement(item.i, getState().length) }
+ })
+ )
+
+ decIndex()
+}
diff --git a/assets/ts/state.ts b/assets/ts/state.ts
new file mode 100644
index 0000000..4aebfe9
--- /dev/null
+++ b/assets/ts/state.ts
@@ -0,0 +1,68 @@
+import { increment, decrement } from './utils'
+import { updateIndexText, updateThresholdText } from './nav'
+
+const thresholds = [
+ { threshold: 20, trailLength: 20 },
+ { threshold: 40, trailLength: 10 },
+ { threshold: 80, trailLength: 5 },
+ { threshold: 140, trailLength: 5 },
+ { threshold: 200, trailLength: 5 }
+]
+
+const defaultState = {
+ index: -1,
+ length: 0,
+ threshold: thresholds[2].threshold,
+ trailLength: thresholds[2].trailLength
+}
+
+export type State = typeof defaultState
+
+let state = defaultState
+
+export function getState(): State {
+ // return a copy of state
+ return Object.create(
+ Object.getPrototypeOf(state),
+ Object.getOwnPropertyDescriptors(state)
+ )
+}
+
+export function initState(length: number): void {
+ state.length = length
+}
+
+export function setIndex(index: number): void {
+ state.index = index
+ updateIndexText()
+}
+
+export function incIndex(): void {
+ state.index = increment(state.index, state.length)
+ updateIndexText()
+}
+
+export function decIndex(): void {
+ state.index = decrement(state.index, state.length)
+ updateIndexText()
+}
+
+export function incThreshold(): void {
+ state = updateThreshold(state, 1)
+ updateThresholdText()
+}
+
+export function decThreshold(): void {
+ state = updateThreshold(state, -1)
+ updateThresholdText()
+}
+
+// helper
+
+function updateThreshold(state: State, inc: number): State {
+ const i = thresholds.findIndex((t) => state.threshold === t.threshold)
+ const newItems = thresholds[i + inc]
+ // out of range
+ if (!newItems) return state
+ return { ...state, ...newItems }
+}
diff --git a/assets/ts/thresholdCtl.ts b/assets/ts/thresholdCtl.ts
deleted file mode 100644
index 30f2a21..0000000
--- a/assets/ts/thresholdCtl.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { duper } from './utils'
-import { setStackDepth } from './desktop'
-
-// get threshold display element
-const thresholdDisp = document.getElementsByClassName('thid').item(0) as HTMLSpanElement
-
-// threshold data
-const threshold: number[] = [0, 40, 80, 120, 160, 200]
-export const thresholdSensitivityArray: number[] = [100, 40, 18, 14, 9, 5]
-export let thresholdIndex: number = 2
-
-export const stackDepthArray: number[] = [15, 8, 5, 5, 5, 5]
-
-// update inner text of threshold display element
-const thresholdUpdate = (): void => {
- thresholdDisp.innerText = duper(threshold[thresholdIndex])
-}
-
-const stackDepthUpdate = (): void => {
- setStackDepth(stackDepthArray[thresholdIndex])
-}
-
-// threshold control initialization
-export const thresholdCtlInit = (): void => {
- thresholdUpdate()
- const dec = document.getElementById('thresholdDec') as HTMLButtonElement
- dec.addEventListener(
- 'click',
- function () {
- if (thresholdIndex > 0) {
- thresholdIndex--
- thresholdUpdate()
- stackDepthUpdate()
- }
- },
- { passive: true }
- )
-
- const inc = document.getElementById('thresholdInc') as HTMLButtonElement
- inc.addEventListener(
- 'click',
- function () {
- if (thresholdIndex < 5) {
- thresholdIndex++
- thresholdUpdate()
- stackDepthUpdate()
- }
- },
- { passive: true }
- )
-}
diff --git a/assets/ts/utils.ts b/assets/ts/utils.ts
index 04da9fa..e2e21e7 100644
--- a/assets/ts/utils.ts
+++ b/assets/ts/utils.ts
@@ -1,145 +1,33 @@
-export interface ImageData {
- index: string
- url: string
- imgH: string
- imgW: string
- pColor: string
- sColor: string
+export function increment(num: number, length: number): number {
+ return (num + 1) % length
}
-export interface position {
- x: number
- y: number
+export function decrement(num: number, length: number): number {
+ return (num + length - 1) % length
}
-export interface deviceType {
- mobile: boolean
- tablet: boolean
- desktop: boolean
-}
-
-// 0 to 0001, 25 to 0025
-export const duper = (num: number): string => {
+export function expand(num: number): string {
return ('0000' + num.toString()).slice(-4)
}
-export const mouseToTransform = (
- x: number,
- y: number,
- centerCorrection: boolean = true,
- accelerate: boolean = false
-): string => {
- return `translate${accelerate ? '3d' : ''}(${
- centerCorrection ? `calc(${x}px - 50%)` : `${x}px`
- }, ${centerCorrection ? `calc(${y}px - 50%)` : `${y}px`}${accelerate ? ', 0' : ''})`
+export function isMobile(): boolean {
+ return window.matchMedia('(hover: none)').matches
}
-// eslint-disable-next-line @typescript-eslint/promise-function-async
-export function delay(ms: number): Promise {
- return new Promise((resolve) => setTimeout(resolve, ms))
-}
+export class Watchable {
+ constructor(private obj: T) {}
+ private watchers: (() => void)[] = []
-// remove all event listeners from a node
-export const removeAllEventListeners = (e: Node): Node => {
- return e.cloneNode(true)
-}
-
-// center top div
-export const center = (e: HTMLElement): void => {
- const x: number = window.innerWidth / 2
- let y: number
- if (window.innerWidth > 768) {
- y = (window.innerHeight - 38) / 2
- } else {
- y = (window.innerHeight - 31) / 2 + 31
+ get(): T {
+ return this.obj
}
- e.style.transform = mouseToTransform(x, y)
-}
-export const createImgElement = (input: ImageData): HTMLImageElement => {
- const img = document.createElement('img')
- img.setAttribute('src', input.url)
- img.setAttribute('alt', '')
- img.setAttribute('height', input.imgH)
- img.setAttribute('width', input.imgW)
- img.style.visibility = 'hidden'
- img.dataset.status = 'trail'
- // img.style.backgroundImage = `linear-gradient(15deg, ${input.pColor}, ${input.sColor})`
- return img
-}
+ set(e: T): void {
+ this.obj = e
+ this.watchers.forEach((watcher) => watcher())
+ }
-export const calcImageIndex = (index: number, imgCounts: number): number => {
- if (index >= 0) {
- return index % imgCounts
- } else {
- return (imgCounts + (index % imgCounts)) % imgCounts
+ addWatcher(watcher: () => void): void {
+ this.watchers.push(watcher)
}
}
-
-export const preloadImage = (src: string): void => {
- const cache = new Image()
- cache.src = src
-}
-
-export const getDeviceType = (): deviceType => {
- const ua: string = navigator.userAgent
- const result: deviceType = { mobile: false, tablet: false, desktop: false }
- if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {
- result.mobile = true
- result.tablet = true
- } else if (
- /Mobile|iP(hone|od)|Android|BlackBerry|IEMobile|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(
- ua
- )
- ) {
- result.mobile = true
- } else result.desktop = true
- return result
-}
-
-export const hideImage = (e: HTMLImageElement): void => {
- e.style.visibility = 'hidden'
- e.dataset.status = 'trail'
-}
-
-export const pushIndex = (
- index: number,
- indexesArray: number[],
- stackDepth: number,
- imagesArray: NodeListOf,
- imagesArrayLen: number,
- invertFlag: boolean = false,
- autoHideFlag: boolean = true
-): number => {
- let indexesNum: number = indexesArray.length
- // create variable overflow to store the tail index
- let overflow: number
- if (!invertFlag) {
- // if stack is full, push the tail index out and hide the image
- if (indexesNum === stackDepth) {
- // insert
- indexesArray.push(index)
- // pop out
- overflow = indexesArray.shift() as number
- // auto hide tail image
- if (autoHideFlag) hideImage(imagesArray[overflow])
- } else {
- indexesArray.push(index)
- indexesNum += 1
- }
- } else {
- // if stack is full, push the tail index out and hide the image
- if (indexesNum === stackDepth) {
- // insert
- indexesArray.unshift(calcImageIndex(index - stackDepth + 1, imagesArrayLen))
- // pop out
- overflow = indexesArray.pop() as number
- // auto hide tail image
- if (autoHideFlag) hideImage(imagesArray[overflow])
- } else {
- indexesArray.unshift(calcImageIndex(index - indexesNum + 1, imagesArrayLen))
- indexesNum += 1
- }
- }
- return indexesNum
-}
diff --git a/layouts/index.html b/layouts/index.html
index edb54b2..9fe8cfc 100644
--- a/layouts/index.html
+++ b/layouts/index.html
@@ -1,43 +1,42 @@
-
+
-
-
-
- {{ partial "head.html" . }}
- {{ .Title }}
-
-
-
- {{ partial "header.html" . }}
-
-
- {{ $sourcePath := "images" }}
- {{ $gallery := site.GetPage $sourcePath }}
- {{ with $gallery.Resources.ByType "image" }}
- {{ $index := len . }}
- {{ $.Scratch.Add "img" slice }}
- {{ range . }}
- {{ $index = sub $index 1}}
- {{ $colors := .Colors }}
- {{ $pColor := index $colors 0 }}
- {{ $sColor := "#ccc" }}
- {{ if gt (len $colors) 1 }}
- {{ $sColor = index $colors 1 }}
+
+
+
+ {{ partial "head.html" . }}
+
{{ .Title }}
+
+
+
+ {{ partial "header.html" . }}
+
+
+ {{ $sourcePath := "images" }}
+ {{ $gallery := site.GetPage $sourcePath }}
+ {{ with $gallery.Resources.ByType "image" }}
+ {{ $index := len . }}
+ {{ $.Scratch.Add "img" slice }}
+ {{ range . }}
+ {{ $index = sub $index 1 }}
+ {{ $colors := .Colors }}
+ {{ $pColor := index $colors 0 }}
+ {{ $sColor := "#ccc" }}
+ {{ if gt (len $colors) 1 }}
+ {{ $sColor = index $colors 1 }}
+ {{ end }}
+ {{ $resize := .Resize "x2000 webp Lanczos q70" }}
+ {{ $.Scratch.Add "img" (dict
+ "index" (int $index)
+ "url" (string .RelPermalink)
+ "imgH" (int .Height)
+ "imgW" (int .Width)
+ "pColor" (string $pColor)
+ "sColor" (string $sColor))
+ }}
+ {{ end }}
+
{{ end }}
- {{ $resize := .Resize "x2000 webp Lanczos q70" }}
- {{ $.Scratch.Add "img" (dict
- "index" (string $index)
- "url" (string .RelPermalink)
- "imgH" (string .Height)
- "imgW" (string .Width)
- "pColor" (string $pColor)
- "sColor" (string $sColor)) }}
- {{ end }}
-
- {{ end }}
-
-
-
+
+ {{ partial "nav.html" . }}
+
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index 9c3d6da..c3d84e6 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -3,6 +3,7 @@
{{- $options := dict "targetPath" "css/style.min.css" "enableSourceMap" true -}}
{{- $style = dict "Context" . "ToCSS" $options | merge $style -}}
{{- partial "plugin/style.html" $style -}}
+{{- $esBuildOpts := dict "minify" hugo.IsProduction -}}
-{{ $script := resources.Get "ts/main.ts" | js.Build }}
-
\ No newline at end of file
+{{- $script := resources.Get "ts/main.ts" | js.Build $esBuildOpts -}}
+
diff --git a/layouts/partials/nav.html b/layouts/partials/nav.html
new file mode 100644
index 0000000..f1b9a4a
--- /dev/null
+++ b/layouts/partials/nav.html
@@ -0,0 +1,27 @@
+
diff --git a/package.json b/package.json
index b3c2d2b..baa9db1 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,10 @@
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-promise": "^6.1.1",
"prettier": "3.0.3",
+ "prettier-plugin-go-template": "^0.0.15",
"typescript": "^5.1.6"
+ },
+ "dependencies": {
+ "gsap": "^3.12.2"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..7e4ecca
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,2088 @@
+lockfileVersion: '6.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+dependencies:
+ gsap:
+ specifier: ^3.12.2
+ version: 3.12.2
+
+devDependencies:
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^6.3.0
+ version: 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)(typescript@5.1.6)
+ '@typescript-eslint/parser':
+ specifier: ^6.3.0
+ version: 6.3.0(eslint@8.47.0)(typescript@5.1.6)
+ eslint:
+ specifier: ^8.47.0
+ version: 8.47.0
+ eslint-config-prettier:
+ specifier: ^9.0.0
+ version: 9.0.0(eslint@8.47.0)
+ eslint-config-standard:
+ specifier: ^17.1.0
+ version: 17.1.0(eslint-plugin-import@2.28.0)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.47.0)
+ eslint-config-standard-with-typescript:
+ specifier: ^37.0.0
+ version: 37.0.0(@typescript-eslint/eslint-plugin@6.3.0)(eslint-plugin-import@2.28.0)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.47.0)(typescript@5.1.6)
+ eslint-plugin-import:
+ specifier: ^2.28.0
+ version: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)
+ eslint-plugin-n:
+ specifier: ^16.0.1
+ version: 16.0.1(eslint@8.47.0)
+ eslint-plugin-prettier:
+ specifier: ^5.0.0
+ version: 5.0.0(eslint-config-prettier@9.0.0)(eslint@8.47.0)(prettier@3.0.1)
+ eslint-plugin-promise:
+ specifier: ^6.1.1
+ version: 6.1.1(eslint@8.47.0)
+ prettier:
+ specifier: 3.0.1
+ version: 3.0.1
+ prettier-plugin-go-template:
+ specifier: ^0.0.15
+ version: 0.0.15(prettier@3.0.1)
+ typescript:
+ specifier: ^5.1.6
+ version: 5.1.6
+
+packages:
+
+ /@aashutoshrathi/word-wrap@1.2.6:
+ resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.47.0):
+ resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ dependencies:
+ eslint: 8.47.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /@eslint-community/regexpp@4.6.2:
+ resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+ dev: true
+
+ /@eslint/eslintrc@2.1.2:
+ resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.4
+ espree: 9.6.1
+ globals: 13.21.0
+ ignore: 5.2.4
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@eslint/js@8.47.0:
+ resolution: {integrity: sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /@humanwhocodes/config-array@0.11.10:
+ resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 1.2.1
+ debug: 4.3.4
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@humanwhocodes/module-importer@1.0.1:
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+ dev: true
+
+ /@humanwhocodes/object-schema@1.2.1:
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
+ dev: true
+
+ /@nodelib/fs.scandir@2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+ dev: true
+
+ /@nodelib/fs.stat@2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /@nodelib/fs.walk@1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.15.0
+ dev: true
+
+ /@pkgr/utils@2.4.2:
+ resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ dependencies:
+ cross-spawn: 7.0.3
+ fast-glob: 3.3.1
+ is-glob: 4.0.3
+ open: 9.1.0
+ picocolors: 1.0.0
+ tslib: 2.6.1
+ dev: true
+
+ /@types/json-schema@7.0.12:
+ resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
+ dev: true
+
+ /@types/json5@0.0.29:
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ dev: true
+
+ /@types/semver@7.5.0:
+ resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
+ dev: true
+
+ /@typescript-eslint/eslint-plugin@6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@eslint-community/regexpp': 4.6.2
+ '@typescript-eslint/parser': 6.3.0(eslint@8.47.0)(typescript@5.1.6)
+ '@typescript-eslint/scope-manager': 6.3.0
+ '@typescript-eslint/type-utils': 6.3.0(eslint@8.47.0)(typescript@5.1.6)
+ '@typescript-eslint/utils': 6.3.0(eslint@8.47.0)(typescript@5.1.6)
+ '@typescript-eslint/visitor-keys': 6.3.0
+ debug: 4.3.4
+ eslint: 8.47.0
+ graphemer: 1.4.0
+ ignore: 5.2.4
+ natural-compare: 1.4.0
+ natural-compare-lite: 1.4.0
+ semver: 7.5.4
+ ts-api-utils: 1.0.1(typescript@5.1.6)
+ typescript: 5.1.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/parser@5.62.0(eslint@8.47.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 5.62.0
+ '@typescript-eslint/types': 5.62.0
+ '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6)
+ debug: 4.3.4
+ eslint: 8.47.0
+ typescript: 5.1.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/parser@6.3.0(eslint@8.47.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 6.3.0
+ '@typescript-eslint/types': 6.3.0
+ '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6)
+ '@typescript-eslint/visitor-keys': 6.3.0
+ debug: 4.3.4
+ eslint: 8.47.0
+ typescript: 5.1.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/scope-manager@5.62.0:
+ resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.62.0
+ '@typescript-eslint/visitor-keys': 5.62.0
+ dev: true
+
+ /@typescript-eslint/scope-manager@6.3.0:
+ resolution: {integrity: sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.3.0
+ '@typescript-eslint/visitor-keys': 6.3.0
+ dev: true
+
+ /@typescript-eslint/type-utils@6.3.0(eslint@8.47.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6)
+ '@typescript-eslint/utils': 6.3.0(eslint@8.47.0)(typescript@5.1.6)
+ debug: 4.3.4
+ eslint: 8.47.0
+ ts-api-utils: 1.0.1(typescript@5.1.6)
+ typescript: 5.1.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/types@5.62.0:
+ resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /@typescript-eslint/types@6.3.0:
+ resolution: {integrity: sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dev: true
+
+ /@typescript-eslint/typescript-estree@5.62.0(typescript@5.1.6):
+ resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 5.62.0
+ '@typescript-eslint/visitor-keys': 5.62.0
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.5.4
+ tsutils: 3.21.0(typescript@5.1.6)
+ typescript: 5.1.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/typescript-estree@6.3.0(typescript@5.1.6):
+ resolution: {integrity: sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 6.3.0
+ '@typescript-eslint/visitor-keys': 6.3.0
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.5.4
+ ts-api-utils: 1.0.1(typescript@5.1.6)
+ typescript: 5.1.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/utils@6.3.0(eslint@8.47.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0)
+ '@types/json-schema': 7.0.12
+ '@types/semver': 7.5.0
+ '@typescript-eslint/scope-manager': 6.3.0
+ '@typescript-eslint/types': 6.3.0
+ '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6)
+ eslint: 8.47.0
+ semver: 7.5.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
+ /@typescript-eslint/visitor-keys@5.62.0:
+ resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.62.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /@typescript-eslint/visitor-keys@6.3.0:
+ resolution: {integrity: sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.3.0
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /acorn-jsx@5.3.2(acorn@8.10.0):
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ acorn: 8.10.0
+ dev: true
+
+ /acorn@8.10.0:
+ resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ dev: true
+
+ /ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+ dev: true
+
+ /ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+ dependencies:
+ color-convert: 2.0.1
+ dev: true
+
+ /argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ dev: true
+
+ /array-buffer-byte-length@1.0.0:
+ resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
+ dependencies:
+ call-bind: 1.0.2
+ is-array-buffer: 3.0.2
+ dev: true
+
+ /array-includes@3.1.6:
+ resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ get-intrinsic: 1.2.1
+ is-string: 1.0.7
+ dev: true
+
+ /array-union@2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /array.prototype.findlastindex@1.2.2:
+ resolution: {integrity: sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ es-shim-unscopables: 1.0.0
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /array.prototype.flat@1.3.1:
+ resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ es-shim-unscopables: 1.0.0
+ dev: true
+
+ /array.prototype.flatmap@1.3.1:
+ resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ es-shim-unscopables: 1.0.0
+ dev: true
+
+ /arraybuffer.prototype.slice@1.0.1:
+ resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-buffer-byte-length: 1.0.0
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ get-intrinsic: 1.2.1
+ is-array-buffer: 3.0.2
+ is-shared-array-buffer: 1.0.2
+ dev: true
+
+ /available-typed-arrays@1.0.5:
+ resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ dev: true
+
+ /big-integer@1.6.51:
+ resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==}
+ engines: {node: '>=0.6'}
+ dev: true
+
+ /bplist-parser@0.2.0:
+ resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==}
+ engines: {node: '>= 5.10.0'}
+ dependencies:
+ big-integer: 1.6.51
+ dev: true
+
+ /brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+ dev: true
+
+ /braces@3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+ dev: true
+
+ /builtins@5.0.1:
+ resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==}
+ dependencies:
+ semver: 7.5.4
+ dev: true
+
+ /bundle-name@3.0.0:
+ resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==}
+ engines: {node: '>=12'}
+ dependencies:
+ run-applescript: 5.0.0
+ dev: true
+
+ /call-bind@1.0.2:
+ resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+ dependencies:
+ function-bind: 1.1.1
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+ dev: true
+
+ /color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+ dependencies:
+ color-name: 1.1.4
+ dev: true
+
+ /color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ dev: true
+
+ /concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+ dev: true
+
+ /cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+ dev: true
+
+ /debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.3
+ dev: true
+
+ /debug@4.3.4:
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.2
+ dev: true
+
+ /deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+ dev: true
+
+ /default-browser-id@3.0.0:
+ resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==}
+ engines: {node: '>=12'}
+ dependencies:
+ bplist-parser: 0.2.0
+ untildify: 4.0.0
+ dev: true
+
+ /default-browser@4.0.0:
+ resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==}
+ engines: {node: '>=14.16'}
+ dependencies:
+ bundle-name: 3.0.0
+ default-browser-id: 3.0.0
+ execa: 7.2.0
+ titleize: 3.0.0
+ dev: true
+
+ /define-lazy-prop@3.0.0:
+ resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /define-properties@1.2.0:
+ resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-property-descriptors: 1.0.0
+ object-keys: 1.1.1
+ dev: true
+
+ /dir-glob@3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-type: 4.0.0
+ dev: true
+
+ /doctrine@2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
+ /doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
+ /es-abstract@1.22.1:
+ resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-buffer-byte-length: 1.0.0
+ arraybuffer.prototype.slice: 1.0.1
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ es-set-tostringtag: 2.0.1
+ es-to-primitive: 1.2.1
+ function.prototype.name: 1.1.5
+ get-intrinsic: 1.2.1
+ get-symbol-description: 1.0.0
+ globalthis: 1.0.3
+ gopd: 1.0.1
+ has: 1.0.3
+ has-property-descriptors: 1.0.0
+ has-proto: 1.0.1
+ has-symbols: 1.0.3
+ internal-slot: 1.0.5
+ is-array-buffer: 3.0.2
+ is-callable: 1.2.7
+ is-negative-zero: 2.0.2
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.2
+ is-string: 1.0.7
+ is-typed-array: 1.1.12
+ is-weakref: 1.0.2
+ object-inspect: 1.12.3
+ object-keys: 1.1.1
+ object.assign: 4.1.4
+ regexp.prototype.flags: 1.5.0
+ safe-array-concat: 1.0.0
+ safe-regex-test: 1.0.0
+ string.prototype.trim: 1.2.7
+ string.prototype.trimend: 1.0.6
+ string.prototype.trimstart: 1.0.6
+ typed-array-buffer: 1.0.0
+ typed-array-byte-length: 1.0.0
+ typed-array-byte-offset: 1.0.0
+ typed-array-length: 1.0.4
+ unbox-primitive: 1.0.2
+ which-typed-array: 1.1.11
+ dev: true
+
+ /es-set-tostringtag@2.0.1:
+ resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.1
+ has: 1.0.3
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /es-shim-unscopables@1.0.0:
+ resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
+ dependencies:
+ has: 1.0.3
+ dev: true
+
+ /es-to-primitive@1.2.1:
+ resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-callable: 1.2.7
+ is-date-object: 1.0.5
+ is-symbol: 1.0.4
+ dev: true
+
+ /escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /eslint-config-prettier@9.0.0(eslint@8.47.0):
+ resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==}
+ hasBin: true
+ peerDependencies:
+ eslint: '>=7.0.0'
+ dependencies:
+ eslint: 8.47.0
+ dev: true
+
+ /eslint-config-standard-with-typescript@37.0.0(@typescript-eslint/eslint-plugin@6.3.0)(eslint-plugin-import@2.28.0)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.47.0)(typescript@5.1.6):
+ resolution: {integrity: sha512-V8I/Q1eFf9tiOuFHkbksUdWO3p1crFmewecfBtRxXdnvb71BCJx+1xAknlIRZMwZioMX3/bPtMVCZsf1+AjjOw==}
+ peerDependencies:
+ '@typescript-eslint/eslint-plugin': ^5.52.0
+ eslint: ^8.0.1
+ eslint-plugin-import: ^2.25.2
+ eslint-plugin-n: '^15.0.0 || ^16.0.0 '
+ eslint-plugin-promise: ^6.0.0
+ typescript: '*'
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)(typescript@5.1.6)
+ '@typescript-eslint/parser': 5.62.0(eslint@8.47.0)(typescript@5.1.6)
+ eslint: 8.47.0
+ eslint-config-standard: 17.1.0(eslint-plugin-import@2.28.0)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.47.0)
+ eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)
+ eslint-plugin-n: 16.0.1(eslint@8.47.0)
+ eslint-plugin-promise: 6.1.1(eslint@8.47.0)
+ typescript: 5.1.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /eslint-config-standard@17.1.0(eslint-plugin-import@2.28.0)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.47.0):
+ resolution: {integrity: sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ eslint: ^8.0.1
+ eslint-plugin-import: ^2.25.2
+ eslint-plugin-n: '^15.0.0 || ^16.0.0 '
+ eslint-plugin-promise: ^6.0.0
+ dependencies:
+ eslint: 8.47.0
+ eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)
+ eslint-plugin-n: 16.0.1(eslint@8.47.0)
+ eslint-plugin-promise: 6.1.1(eslint@8.47.0)
+ dev: true
+
+ /eslint-import-resolver-node@0.3.9:
+ resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
+ dependencies:
+ debug: 3.2.7
+ is-core-module: 2.13.0
+ resolve: 1.22.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint@8.47.0):
+ resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 6.3.0(eslint@8.47.0)(typescript@5.1.6)
+ debug: 3.2.7
+ eslint: 8.47.0
+ eslint-import-resolver-node: 0.3.9
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /eslint-plugin-es-x@7.2.0(eslint@8.47.0):
+ resolution: {integrity: sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '>=8'
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0)
+ '@eslint-community/regexpp': 4.6.2
+ eslint: 8.47.0
+ dev: true
+
+ /eslint-plugin-import@2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0):
+ resolution: {integrity: sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 6.3.0(eslint@8.47.0)(typescript@5.1.6)
+ array-includes: 3.1.6
+ array.prototype.findlastindex: 1.2.2
+ array.prototype.flat: 1.3.1
+ array.prototype.flatmap: 1.3.1
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.47.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint@8.47.0)
+ has: 1.0.3
+ is-core-module: 2.13.0
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.fromentries: 2.0.6
+ object.groupby: 1.0.0
+ object.values: 1.1.6
+ resolve: 1.22.4
+ semver: 6.3.1
+ tsconfig-paths: 3.14.2
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+ dev: true
+
+ /eslint-plugin-n@16.0.1(eslint@8.47.0):
+ resolution: {integrity: sha512-CDmHegJN0OF3L5cz5tATH84RPQm9kG+Yx39wIqIwPR2C0uhBGMWfbbOtetR83PQjjidA5aXMu+LEFw1jaSwvTA==}
+ engines: {node: '>=16.0.0'}
+ peerDependencies:
+ eslint: '>=7.0.0'
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0)
+ builtins: 5.0.1
+ eslint: 8.47.0
+ eslint-plugin-es-x: 7.2.0(eslint@8.47.0)
+ ignore: 5.2.4
+ is-core-module: 2.13.0
+ minimatch: 3.1.2
+ resolve: 1.22.4
+ semver: 7.5.4
+ dev: true
+
+ /eslint-plugin-prettier@5.0.0(eslint-config-prettier@9.0.0)(eslint@8.47.0)(prettier@3.0.1):
+ resolution: {integrity: sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ '@types/eslint': '>=8.0.0'
+ eslint: '>=8.0.0'
+ eslint-config-prettier: '*'
+ prettier: '>=3.0.0'
+ peerDependenciesMeta:
+ '@types/eslint':
+ optional: true
+ eslint-config-prettier:
+ optional: true
+ dependencies:
+ eslint: 8.47.0
+ eslint-config-prettier: 9.0.0(eslint@8.47.0)
+ prettier: 3.0.1
+ prettier-linter-helpers: 1.0.0
+ synckit: 0.8.5
+ dev: true
+
+ /eslint-plugin-promise@6.1.1(eslint@8.47.0):
+ resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ dependencies:
+ eslint: 8.47.0
+ dev: true
+
+ /eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+ dev: true
+
+ /eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /eslint@8.47.0:
+ resolution: {integrity: sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ hasBin: true
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0)
+ '@eslint-community/regexpp': 4.6.2
+ '@eslint/eslintrc': 2.1.2
+ '@eslint/js': 8.47.0
+ '@humanwhocodes/config-array': 0.11.10
+ '@humanwhocodes/module-importer': 1.0.1
+ '@nodelib/fs.walk': 1.2.8
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.4
+ doctrine: 3.0.0
+ escape-string-regexp: 4.0.0
+ eslint-scope: 7.2.2
+ eslint-visitor-keys: 3.4.3
+ espree: 9.6.1
+ esquery: 1.5.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ globals: 13.21.0
+ graphemer: 1.4.0
+ ignore: 5.2.4
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ is-path-inside: 3.0.3
+ js-yaml: 4.1.0
+ json-stable-stringify-without-jsonify: 1.0.1
+ levn: 0.4.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.2
+ natural-compare: 1.4.0
+ optionator: 0.9.3
+ strip-ansi: 6.0.1
+ text-table: 0.2.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ acorn: 8.10.0
+ acorn-jsx: 5.3.2(acorn@8.10.0)
+ eslint-visitor-keys: 3.4.3
+ dev: true
+
+ /esquery@1.5.0:
+ resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+ dev: true
+
+ /esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /execa@5.1.1:
+ resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+ engines: {node: '>=10'}
+ dependencies:
+ cross-spawn: 7.0.3
+ get-stream: 6.0.1
+ human-signals: 2.1.0
+ is-stream: 2.0.1
+ merge-stream: 2.0.0
+ npm-run-path: 4.0.1
+ onetime: 5.1.2
+ signal-exit: 3.0.7
+ strip-final-newline: 2.0.0
+ dev: true
+
+ /execa@7.2.0:
+ resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==}
+ engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0}
+ dependencies:
+ cross-spawn: 7.0.3
+ get-stream: 6.0.1
+ human-signals: 4.3.1
+ is-stream: 3.0.0
+ merge-stream: 2.0.0
+ npm-run-path: 5.1.0
+ onetime: 6.0.0
+ signal-exit: 3.0.7
+ strip-final-newline: 3.0.0
+ dev: true
+
+ /fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ dev: true
+
+ /fast-diff@1.3.0:
+ resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
+ dev: true
+
+ /fast-glob@3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+ dev: true
+
+ /fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+ dev: true
+
+ /fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+ dev: true
+
+ /fastq@1.15.0:
+ resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+ dependencies:
+ reusify: 1.0.4
+ dev: true
+
+ /file-entry-cache@6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flat-cache: 3.0.4
+ dev: true
+
+ /fill-range@7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+ dev: true
+
+ /find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+ dev: true
+
+ /flat-cache@3.0.4:
+ resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flatted: 3.2.7
+ rimraf: 3.0.2
+ dev: true
+
+ /flatted@3.2.7:
+ resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
+ dev: true
+
+ /for-each@0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ dependencies:
+ is-callable: 1.2.7
+ dev: true
+
+ /fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+ dev: true
+
+ /function-bind@1.1.1:
+ resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+ dev: true
+
+ /function.prototype.name@1.1.5:
+ resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ functions-have-names: 1.2.3
+ dev: true
+
+ /functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ dev: true
+
+ /get-intrinsic@1.2.1:
+ resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
+ dependencies:
+ function-bind: 1.1.1
+ has: 1.0.3
+ has-proto: 1.0.1
+ has-symbols: 1.0.3
+ dev: true
+
+ /get-stream@6.0.1:
+ resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /get-symbol-description@1.0.0:
+ resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.3
+ dev: true
+
+ /glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+ dependencies:
+ is-glob: 4.0.3
+ dev: true
+
+ /glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+ dev: true
+
+ /globals@13.21.0:
+ resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==}
+ engines: {node: '>=8'}
+ dependencies:
+ type-fest: 0.20.2
+ dev: true
+
+ /globalthis@1.0.3:
+ resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-properties: 1.2.0
+ dev: true
+
+ /globby@11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.3.1
+ ignore: 5.2.4
+ merge2: 1.4.1
+ slash: 3.0.0
+ dev: true
+
+ /gopd@1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+ dependencies:
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+ dev: true
+
+ /gsap@3.12.2:
+ resolution: {integrity: sha512-EkYnpG8qHgYBFAwsgsGEqvT1WUidX0tt/ijepx7z8EUJHElykg91RvW1XbkT59T0gZzzszOpjQv7SE41XuIXyQ==}
+ dev: false
+
+ /has-bigints@1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+ dev: true
+
+ /has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /has-property-descriptors@1.0.0:
+ resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
+ dependencies:
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /has-proto@1.0.1:
+ resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /has-symbols@1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /has-tostringtag@1.0.0:
+ resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: true
+
+ /has@1.0.3:
+ resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+ engines: {node: '>= 0.4.0'}
+ dependencies:
+ function-bind: 1.1.1
+ dev: true
+
+ /human-signals@2.1.0:
+ resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
+ engines: {node: '>=10.17.0'}
+ dev: true
+
+ /human-signals@4.3.1:
+ resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==}
+ engines: {node: '>=14.18.0'}
+ dev: true
+
+ /ignore@5.2.4:
+ resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
+ engines: {node: '>= 4'}
+ dev: true
+
+ /import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+ dev: true
+
+ /imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+ dev: true
+
+ /inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+ dev: true
+
+ /inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ dev: true
+
+ /internal-slot@1.0.5:
+ resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.1
+ has: 1.0.3
+ side-channel: 1.0.4
+ dev: true
+
+ /is-array-buffer@3.0.2:
+ resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /is-bigint@1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ dependencies:
+ has-bigints: 1.0.2
+ dev: true
+
+ /is-boolean-object@1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /is-core-module@2.13.0:
+ resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
+ dependencies:
+ has: 1.0.3
+ dev: true
+
+ /is-date-object@1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-docker@2.2.1:
+ resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
+ engines: {node: '>=8'}
+ hasBin: true
+ dev: true
+
+ /is-docker@3.0.0:
+ resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ hasBin: true
+ dev: true
+
+ /is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+ dev: true
+
+ /is-inside-container@1.0.0:
+ resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
+ engines: {node: '>=14.16'}
+ hasBin: true
+ dependencies:
+ is-docker: 3.0.0
+ dev: true
+
+ /is-negative-zero@2.0.2:
+ resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /is-number-object@1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+ dev: true
+
+ /is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /is-regex@1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-shared-array-buffer@1.0.2:
+ resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: true
+
+ /is-stream@2.0.1:
+ resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /is-stream@3.0.0:
+ resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dev: true
+
+ /is-string@1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-symbol@1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: true
+
+ /is-typed-array@1.1.12:
+ resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ which-typed-array: 1.1.11
+ dev: true
+
+ /is-weakref@1.0.2:
+ resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: true
+
+ /is-wsl@2.2.0:
+ resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
+ engines: {node: '>=8'}
+ dependencies:
+ is-docker: 2.2.1
+ dev: true
+
+ /isarray@2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+ dev: true
+
+ /isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ dev: true
+
+ /js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+ dev: true
+
+ /json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ dev: true
+
+ /json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+ dev: true
+
+ /json5@1.0.2:
+ resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.8
+ dev: true
+
+ /levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ dev: true
+
+ /locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-locate: 5.0.0
+ dev: true
+
+ /lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ dev: true
+
+ /lru-cache@6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+ dependencies:
+ yallist: 4.0.0
+ dev: true
+
+ /merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+ dev: true
+
+ /merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /micromatch@4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+ dev: true
+
+ /mimic-fn@2.1.0:
+ resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /mimic-fn@4.0.0:
+ resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ dependencies:
+ brace-expansion: 1.1.11
+ dev: true
+
+ /minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ dev: true
+
+ /ms@2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+ dev: true
+
+ /ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ dev: true
+
+ /natural-compare-lite@1.4.0:
+ resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
+ dev: true
+
+ /natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ dev: true
+
+ /npm-run-path@4.0.1:
+ resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-key: 3.1.1
+ dev: true
+
+ /npm-run-path@5.1.0:
+ resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ path-key: 4.0.0
+ dev: true
+
+ /object-inspect@1.12.3:
+ resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
+ dev: true
+
+ /object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /object.assign@4.1.4:
+ resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+ dev: true
+
+ /object.fromentries@2.0.6:
+ resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ dev: true
+
+ /object.groupby@1.0.0:
+ resolution: {integrity: sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /object.values@1.1.6:
+ resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ dev: true
+
+ /once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+ dev: true
+
+ /onetime@5.1.2:
+ resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+ engines: {node: '>=6'}
+ dependencies:
+ mimic-fn: 2.1.0
+ dev: true
+
+ /onetime@6.0.0:
+ resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ mimic-fn: 4.0.0
+ dev: true
+
+ /open@9.1.0:
+ resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==}
+ engines: {node: '>=14.16'}
+ dependencies:
+ default-browser: 4.0.0
+ define-lazy-prop: 3.0.0
+ is-inside-container: 1.0.0
+ is-wsl: 2.2.0
+ dev: true
+
+ /optionator@0.9.3:
+ resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ '@aashutoshrathi/word-wrap': 1.2.6
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ dev: true
+
+ /p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ yocto-queue: 0.1.0
+ dev: true
+
+ /p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-limit: 3.1.0
+ dev: true
+
+ /parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+ dev: true
+
+ /path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-key@4.0.0:
+ resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+ dev: true
+
+ /path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /picocolors@1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+ dev: true
+
+ /picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+ dev: true
+
+ /prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+ dev: true
+
+ /prettier-linter-helpers@1.0.0:
+ resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ fast-diff: 1.3.0
+ dev: true
+
+ /prettier-plugin-go-template@0.0.15(prettier@3.0.1):
+ resolution: {integrity: sha512-WqU92E1NokWYNZ9mLE6ijoRg6LtIGdLMePt2C7UBDjXeDH9okcRI3zRqtnWR4s5AloiqyvZ66jNBAa9tmRY5EQ==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ prettier: ^3.0.0
+ dependencies:
+ prettier: 3.0.1
+ ulid: 2.3.0
+ dev: true
+
+ /prettier@3.0.1:
+ resolution: {integrity: sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==}
+ engines: {node: '>=14'}
+ hasBin: true
+ dev: true
+
+ /punycode@2.3.0:
+ resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ dev: true
+
+ /regexp.prototype.flags@1.5.0:
+ resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ functions-have-names: 1.2.3
+ dev: true
+
+ /resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /resolve@1.22.4:
+ resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.13.0
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+ dev: true
+
+ /reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ dev: true
+
+ /rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.3
+ dev: true
+
+ /run-applescript@5.0.0:
+ resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==}
+ engines: {node: '>=12'}
+ dependencies:
+ execa: 5.1.1
+ dev: true
+
+ /run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ dependencies:
+ queue-microtask: 1.2.3
+ dev: true
+
+ /safe-array-concat@1.0.0:
+ resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==}
+ engines: {node: '>=0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ has-symbols: 1.0.3
+ isarray: 2.0.5
+ dev: true
+
+ /safe-regex-test@1.0.0:
+ resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-regex: 1.1.4
+ dev: true
+
+ /semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+ dev: true
+
+ /semver@7.5.4:
+ resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+
+ /shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+ dependencies:
+ shebang-regex: 3.0.0
+ dev: true
+
+ /shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /side-channel@1.0.4:
+ resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ object-inspect: 1.12.3
+ dev: true
+
+ /signal-exit@3.0.7:
+ resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+ dev: true
+
+ /slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /string.prototype.trim@1.2.7:
+ resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ dev: true
+
+ /string.prototype.trimend@1.0.6:
+ resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ dev: true
+
+ /string.prototype.trimstart@1.0.6:
+ resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.22.1
+ dev: true
+
+ /strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.1
+ dev: true
+
+ /strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /strip-final-newline@2.0.0:
+ resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /strip-final-newline@3.0.0:
+ resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+ dependencies:
+ has-flag: 4.0.0
+ dev: true
+
+ /supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /synckit@0.8.5:
+ resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ dependencies:
+ '@pkgr/utils': 2.4.2
+ tslib: 2.6.1
+ dev: true
+
+ /text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ dev: true
+
+ /titleize@3.0.0:
+ resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+ dependencies:
+ is-number: 7.0.0
+ dev: true
+
+ /ts-api-utils@1.0.1(typescript@5.1.6):
+ resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==}
+ engines: {node: '>=16.13.0'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+ dependencies:
+ typescript: 5.1.6
+ dev: true
+
+ /tsconfig-paths@3.14.2:
+ resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==}
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.2
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+ dev: true
+
+ /tslib@1.14.1:
+ resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
+ dev: true
+
+ /tslib@2.6.1:
+ resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
+ dev: true
+
+ /tsutils@3.21.0(typescript@5.1.6):
+ resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
+ engines: {node: '>= 6'}
+ peerDependencies:
+ typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
+ dependencies:
+ tslib: 1.14.1
+ typescript: 5.1.6
+ dev: true
+
+ /type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ dev: true
+
+ /type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /typed-array-buffer@1.0.0:
+ resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typed-array-byte-length@1.0.0:
+ resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ has-proto: 1.0.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typed-array-byte-offset@1.0.0:
+ resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ has-proto: 1.0.1
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typed-array-length@1.0.4:
+ resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==}
+ dependencies:
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ is-typed-array: 1.1.12
+ dev: true
+
+ /typescript@5.1.6:
+ resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+ dev: true
+
+ /ulid@2.3.0:
+ resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==}
+ hasBin: true
+ dev: true
+
+ /unbox-primitive@1.0.2:
+ resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+ dependencies:
+ call-bind: 1.0.2
+ has-bigints: 1.0.2
+ has-symbols: 1.0.3
+ which-boxed-primitive: 1.0.2
+ dev: true
+
+ /untildify@4.0.0:
+ resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ dependencies:
+ punycode: 2.3.0
+ dev: true
+
+ /which-boxed-primitive@1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ dependencies:
+ is-bigint: 1.0.4
+ is-boolean-object: 1.1.2
+ is-number-object: 1.0.7
+ is-string: 1.0.7
+ is-symbol: 1.0.4
+ dev: true
+
+ /which-typed-array@1.1.11:
+ resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+ dev: true
+
+ /wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ dev: true
+
+ /yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ dev: true
+
+ /yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+ dev: true
diff --git a/static/fonts/HelveticaNowText-Regular.woff b/static/fonts/HelveticaNowText-Regular.woff
new file mode 100644
index 0000000..5bdb0c5
Binary files /dev/null and b/static/fonts/HelveticaNowText-Regular.woff differ
diff --git a/tsconfig.json b/tsconfig.json
index a7acaa3..3288c16 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -8,8 +8,9 @@
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
- "forceConsistentCasingInFileNames": true
+ "forceConsistentCasingInFileNames": true,
+ "moduleResolution": "node"
},
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Recommended"
-}
\ No newline at end of file
+}