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 "footer.html" . }} -
- +
+ {{ 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 +}