diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..2f03fdd
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,35 @@
+---
+name: Bug Report
+about: Create a bug report to help solve an issue
+title: 'Bug: TITLE'
+labels: New Issue
+assignees: ''
+---
+
+**Describe the issue**
+
+A clear and concise description of what the bug is.
+
+**Expected behavior**
+
+A clear and concise description of what you expected to happen.
+
+**To Reproduce**
+
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+
+**Media**
+
+If applicable, add a screenshot or a video to help explain your problem.
+
+**Needed information (please complete the following information):**
+- **Client Version:**: [e.g. Canary or Release]
+- **Release Version:**: [e.g 1.0]
+
+**Additional context**
+Add any other context about the issue here.
diff --git a/.github/assets/slrn_multijob.png b/.github/assets/slrn_multijob.png
new file mode 100644
index 0000000..f06939f
Binary files /dev/null and b/.github/assets/slrn_multijob.png differ
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..03b20e7
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,45 @@
+name: CI
+on:
+ push:
+ paths:
+ - 'ui/**'
+ - '.github/workflows/ci.yml'
+ pull_request:
+ paths:
+ - 'ui/**'
+ - '.github/workflows/ci.yml'
+jobs:
+ build:
+ name: Build Test
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: ui
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Setup node environment
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20.x
+ cache: "pnpm"
+ cache-dependency-path: "ui/pnpm-lock.yaml"
+
+ - name: Install deps
+ run: pnpm install --frozen-lockfile
+ working-directory: ui
+
+ - name: Try build
+ run: pnpm build
+ working-directory: ui
+ env:
+ CI: true
diff --git a/.github/workflows/debugbuild.yml b/.github/workflows/debugbuild.yml
new file mode 100644
index 0000000..606e318
--- /dev/null
+++ b/.github/workflows/debugbuild.yml
@@ -0,0 +1,56 @@
+name: "Debug Build Action"
+
+on:
+ workflow_dispatch:
+
+jobs:
+ debug-build:
+ name: "Create Debug Build"
+ runs-on: "ubuntu-latest"
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ ref: ${{ github.event.inputs.branch }}
+
+ - name: Install ZIP
+ run: sudo apt install zip
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.0.0
+ with:
+ version: 9
+
+ - name: Setup node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20.x
+ cache: "pnpm"
+ cache-dependency-path: "ui/pnpm-lock.yaml"
+
+ - name: Install dependencies
+ run: pnpm i --frozen-lockfile
+ working-directory: ui
+
+ - name: Run build
+ run: pnpm build
+ working-directory: ui
+ env:
+ CI: false
+
+ - name: Bundle files
+ run: |
+ shopt -s extglob
+ mkdir -p ./temp/${{ github.event.repository.name }}
+ mkdir -p ./temp/${{ github.event.repository.name }}/ui
+ cp ./{README.md,LICENSE,fxmanifest.lua} ./temp/${{ github.event.repository.name }}
+ cp -r ./{client,bridge,server} ./temp/${{ github.event.repository.name }}
+ cp -r ./ui/dist ./temp/${{ github.event.repository.name }}/ui/
+ cd ./temp && zip -r ../${{ github.event.repository.name }}.zip ./${{ github.event.repository.name }}
+
+ - name: Upload Build Artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ github.event.repository.name }}
+ path: ./temp/
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 6baaacd..b67e381 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,5 +1,13 @@
name: Lint
-on: [push, pull_request_target]
+on:
+ push:
+ paths:
+ - '*.lua'
+ - '.github/workflows/lint.yml'
+ pull_request_target:
+ paths:
+ - '*.lua'
+ - '.github/workflows/lint.yml'
jobs:
lint:
name: Lint Resource
@@ -15,7 +23,6 @@ jobs:
args: "-t --formatter JUnit"
extra_libs: ox_lib+mysql+qblocales+qbox+qbox_playerdata+qbox_lib
- name: Generate Lint Report
- if: always()
uses: mikepenz/action-junit-report@v4
with:
report_paths: "**/junit.xml"
diff --git a/.github/workflows/release-action.yml b/.github/workflows/release-action.yml
index feecf0b..18c4bc4 100644
--- a/.github/workflows/release-action.yml
+++ b/.github/workflows/release-action.yml
@@ -19,13 +19,37 @@ jobs:
- name: Install ZIP
run: sudo apt install zip
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4.0.0
+ with:
+ version: 9
+
+ - name: Setup node
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20.x
+ cache: "pnpm"
+ cache-dependency-path: "ui/pnpm-lock.yaml"
+
+ - name: Install dependencies
+ run: pnpm i --frozen-lockfile
+ working-directory: ui
+
+ - name: Run build
+ run: pnpm build
+ working-directory: ui
+ env:
+ CI: false
+
- name: Bundle files
run: |
- rm -rf ./.github ./.vscode ./.git
shopt -s extglob
- mkdir ./${{ github.event.repository.name }}
- cp -r !(${{ github.event.repository.name }}) ${{ github.event.repository.name }}
- zip -r ./${{ github.event.repository.name }}.zip ./${{ github.event.repository.name }}
+ mkdir -p ./temp/${{ github.event.repository.name }}
+ mkdir -p ./temp/${{ github.event.repository.name }}/ui
+ cp ./{README.md,LICENSE,fxmanifest.lua} ./temp/${{ github.event.repository.name }}
+ cp -r ./{client,bridge,server} ./temp/${{ github.event.repository.name }}
+ cp -r ./ui/dist ./temp/${{ github.event.repository.name }}/ui/dist
+ cd ./temp && zip -r ../${{ github.event.repository.name }}.zip ./${{ github.event.repository.name }}
- name: Get App Token
uses: actions/create-github-app-token@v1
diff --git a/README.md b/README.md
index 99971e1..62f6703 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,41 @@
# SLRN Multijob - App for LB-Phone
+![Lint](https://github.com/solareon/slrn_multijob/actions/workflows/lint.yml/badge.svg)
+![CI](https://github.com/solareon/slrn_multijob/actions/workflows/ci.yml/badge.svg)
-A simple lb-phone application to manage the native [qbx_core](https://github.com/qbox-project/qbx_core) multijob. It does not manage multigang, if you wish to do that then you will need to modify the script yourself.
+A simple lb-phone application to manage multijob systems. It does not manage multigang, if you wish to do that then you will need to modify the script yourself.
-# If you are looking for the [qbcore version that is located here](https://github.com/solareon/slrn_qbmultijob)
+**QBOX/QB supported with bridge**
+ESX/ND/OX support soon
# Preview
-![image](https://github.com/solareon/slrn_multijob/assets/769465/eba40145-4255-4993-9527-945ff4eaec0c)
-
+![image](.github/assets/slrn_multijob.png)
+
+# Installation
+Download the [release version](https://github.com/solareon/slrn_groups/releases) and copy to your server.
+
+# Customizing and building from source
+Download the latest commit and navigate to the ui folder
+```bash copy
+pnpm i
+```
+Then to preview the UI. You can also switch the UI path in the app registration (switch the commented lines) and then the game will display the preview running from vite.
+```bash copy
+pnpm start
+```
+Or to build for production
+```bash copy
+pnpm build
+```
# Support
- [Discord](https://discord.gg/TZFBBHvG6E)
# Credits
-- [Randolio](https://github.com/Randolio/randol_multijob) for the multijob natives
+- [Randolio](https://github.com/Randolio/randol_multijob) for the multijob natives for qbox
- [LB-Phone](https://github.com/lbphone/lb-phone-app-template) for the template apps
- [FuZZED105](https://github.com/FuZZED105/fzd_multijob) for the original app
# Dependencies
-- [qbx_core](https://github.com/qbox-project/qbx_core) 1.7.0 or later
- [lb-phone](https://lbphone.com/)
- [ox_lib](https://github.com/overextended/ox_lib)
diff --git a/bridge/esx.lua b/bridge/esx.lua
new file mode 100644
index 0000000..b629021
--- /dev/null
+++ b/bridge/esx.lua
@@ -0,0 +1,17 @@
+if GetResourceState('es_extended') ~= 'started' then return end
+
+if not IsDuplicityVersion() then return end
+
+local ESX = exports.es_extended:getSharedObject()
+
+local function getPlayer(source)
+ return ESX.GetPlayerFromId(source)
+end
+
+---Get the player data from the source
+---@param source number
+---@return string
+function GetPlayerName(source)
+ local xPlayer = getPlayer(source)
+ return xPlayer.getName()
+end
\ No newline at end of file
diff --git a/bridge/nd.lua b/bridge/nd.lua
new file mode 100644
index 0000000..d9dbae8
--- /dev/null
+++ b/bridge/nd.lua
@@ -0,0 +1,19 @@
+if not lib.checkDependency('ND_Core', '2.0.0') then return end
+
+if not IsDuplicityVersion() then return end
+
+NDCore = {}
+
+lib.load('@ND_Core.init')
+
+function GetPlayer(id)
+ return NDCore.getPlayer(id)
+end
+
+---Get the player data from the source
+---@param source number
+---@return string
+function GetPlayerName(source)
+ local player = GetPlayer(source)
+ return player.fullname
+end
diff --git a/bridge/ox.lua b/bridge/ox.lua
new file mode 100644
index 0000000..b468e5e
--- /dev/null
+++ b/bridge/ox.lua
@@ -0,0 +1,8 @@
+if GetResourceState('ox_core') ~= 'started' then return end
+
+local isServer = IsDuplicityVersion()
+
+local Ox = require '@ox_core.lib.init'
+
+--TODO: Add ox_core support
+
diff --git a/bridge/qb.lua b/bridge/qb.lua
new file mode 100644
index 0000000..1bae148
--- /dev/null
+++ b/bridge/qb.lua
@@ -0,0 +1,96 @@
+if GetResourceState('qb-core') ~= 'started' or GetResourceState('qbx_core') == 'started' then return end
+
+QBCore = exports['qb-core']:GetCoreObject()
+local isServer = IsDuplicityVersion()
+
+
+function GetJobs()
+ return QBCore.Shared.Jobs
+end
+
+JOBS = GetJobs()
+
+if isServer then
+ function GetPlayer(source)
+ return QBCore.Functions.GetPlayer(source)
+ end
+
+ function GetPlayerData(source)
+ return GetPlayer(source).PlayerData
+ end
+
+ function Notify(source, message, type)
+ return QBCore.Functions.Notify(source, message, type)
+ end
+
+ function CheckCurrentJob(source, job)
+ local playerData = GetPlayerData(source)
+ return playerData.job.name == job
+ end
+
+ function CanSetJob(source, jobName)
+ local playerData = GetPlayerData(source)
+ local jobs = playerData.jobs
+ for job, _ in pairs(jobs) do
+ if jobName == job then
+ return true
+ end
+ end
+ return false
+ end
+
+ function SetPlayerJob(source, job)
+ return exports.qbx_core:SetPlayerPrimaryJob(GetPlayerData(source).citizenid, job)
+ end
+
+ function RemovePlayerFromJob(source, job)
+ return exports.qbx_core:RemovePlayerFromJob(GetPlayerData(source).citizenid, job)
+ end
+
+ function SetPlayerDuty(source, duty)
+ return GetPlayer(source).Functions.SetJobDuty(duty)
+ end
+
+ AddEventHandler('QBCore:Server:OnJobUpdate', function(playerSource, job)
+ local citizenid = GetPlayerData(playerSource).citizenid
+ if GetPlayerJob(citizenid, job) or GetPlayerJobCount(citizenid) then return end
+ AddPlayerJob(citizenid, job.name, job.grade)
+ end)
+
+ AddEventHandler('QBCore:Server:UpdateObject', function()
+ JOBS = GetJobs()
+ end)
+
+ AddEventHandler('onResourceStart', function(resource)
+ if resource ~= GetCurrentResourceName() then return end
+ MySQL.query([=[
+ CREATE TABLE IF NOT EXISTS `save_jobs` (
+ `cid` VARCHAR(100) NOT NULL,
+ `job` VARCHAR(100) NOT NULL,
+ `grade` INT(11) NOT NULL,
+ UNIQUE KEY `cid_job` (`cid`,`job`)
+ );
+ ]=])
+ end)
+
+else
+ function GetPlayerData()
+ return QBCore.Functions.GetPlayerData()
+ end
+
+ function Notify(message, type)
+ return QBCore.Functions.Notify(message, type)
+ end
+
+ AddEventHandler('QBCore:Client:OnSharedUpdate', function(data)
+ Wait(0)
+ if data ~= 'Jobs' then return end
+ JOBS = GetJobs()
+ end)
+
+ AddEventHandler('QBCore:Client:OnSharedUpdateMultiple', function(data)
+ Wait(0)
+ if data ~= 'Jobs' then return end
+ JOBS = GetJobs()
+ end)
+end
diff --git a/bridge/qbx.lua b/bridge/qbx.lua
new file mode 100644
index 0000000..190449e
--- /dev/null
+++ b/bridge/qbx.lua
@@ -0,0 +1,70 @@
+if GetResourceState('qbx_core') ~= 'started' then return end
+
+if not lib.checkDependency('qbx_core', '1.7.0') then error() end
+
+local isServer = IsDuplicityVersion()
+
+function GetJobs()
+ return exports.qbx_core:GetJobs()
+end
+
+JOBS = GetJobs()
+
+if isServer then
+ function GetPlayer(source)
+ return exports.qbx_core:GetPlayer(source)
+ end
+
+ function GetPlayerData(source)
+ return GetPlayer(source).PlayerData
+ end
+
+ function Notify(source, message, type)
+ return exports.qbx_core:Notify(source, message, type)
+ end
+
+ function CheckCurrentJob(source, job)
+ local playerData = GetPlayerData(source)
+ return playerData.job.name == job
+ end
+
+ function CanSetJob(source, jobName)
+ local playerData = GetPlayerData(source)
+ local jobs = playerData.jobs
+ for job, _ in pairs(jobs) do
+ if jobName == job then
+ return true
+ end
+ end
+ return false
+ end
+
+ function SetPlayerJob(source, job)
+ return exports.qbx_core:SetPlayerPrimaryJob(GetPlayerData(source).citizenid, job)
+ end
+
+ function RemovePlayerFromJob(source, job)
+ return exports.qbx_core:RemovePlayerFromJob(GetPlayerData(source).citizenid, job)
+ end
+
+ function SetPlayerDuty(source, duty)
+ return GetPlayer(source).Functions.SetJobDuty(duty)
+ end
+
+ AddEventHandler('qbx_core:server:onJobUpdate', function()
+ JOBS = GetJobs()
+ end)
+
+else
+ function GetPlayerData()
+ return exports.qbx_core:GetPlayerData()
+ end
+
+ function Notify(message, type)
+ return exports.qbx_core:Notify(message, type)
+ end
+
+ AddEventHandler('qbx_core:client:onJobUpdate', function()
+ JOBS = GetJobs()
+ end)
+end
diff --git a/bridge/storage.lua b/bridge/storage.lua
new file mode 100644
index 0000000..7e3e9c7
--- /dev/null
+++ b/bridge/storage.lua
@@ -0,0 +1,58 @@
+if not IsDuplicityVersion() then return end
+
+local config = lib.load('config')
+
+function GetPlayerJob(identifier, job)
+ local result = MySQL.Sync.fetchAll('SELECT * FROM save_jobs WHERE cid = ? AND job = ? and grade = ?', { identifier, job.name, job.grade })
+ if result[1] then
+ return result[1]
+ end
+ return nil
+end
+
+function GetPlayerJobs(identifier)
+ return MySQL.Sync.fetchAll('SELECT * FROM save_jobs WHERE cid = ?', { identifier })
+end
+
+function SortPlayerJobs(identifier)
+ local result = GetPlayerJobs(identifier)
+ local storeJobs = {}
+ for _, v in pairs(result) do
+ local job = JOBS[v.job]
+
+ if not job then
+ return error(('MISSING JOB FROM jobs.lua: "%s" | CITIZEN ID: %s'):format(v.job, identifier))
+ end
+
+ local grade = job.grades[tostring(v.grade)]
+
+ if not grade then
+ return error(('MISSING JOB GRADE for "%s". GRADE MISSING: %s | CITIZEN ID: %s'):format(v.job, v.grade, identifier))
+ end
+
+ storeJobs[#storeJobs + 1] = {
+ job = v.job,
+ salary = grade.payment,
+ jobLabel = job.label,
+ gradeLabel = grade.name,
+ grade = v.grade,
+ }
+ end
+ return storeJobs
+end
+
+function GetPlayerJobCount(identifier)
+ local result = MySQL.Sync.await('SELECT COUNT(*) as count FROM save_jobs WHERE cid = ?', { identifier })
+ if result[1] then
+ return result[1].count >= config.maxJobs
+ end
+ return false
+end
+
+function AddPlayerJob(identifier, job, grade)
+ return MySQL.Sync.await('INSERT INTO save_jobs (cid, job, grade) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE grade = VALUES(grade)', { identifier, job, grade })
+end
+
+function DeletePlayerJob(identifier, job)
+ return MySQL.Sync.await('DELETE FROM save_jobs WHERE cid = ? AND job = ?', { identifier, job })
+end
\ No newline at end of file
diff --git a/client/cl_main.lua b/client/main.lua
similarity index 67%
rename from client/cl_main.lua
rename to client/main.lua
index 4fbeba6..f8053d8 100644
--- a/client/cl_main.lua
+++ b/client/main.lua
@@ -1,33 +1,41 @@
+local identifier = 'slrn_multijob'
+
if GetCurrentResourceName() ~= 'slrn_multijob' then
lib.print.error('This resource needs to be named ^5slrn_multijob^7.')
return
end
-local sharedJobs = exports.qbx_core:GetJobs()
-
-local function AddApp()
- local added, errorMessage = exports['lb-phone']:AddCustomApp({
- identifier = 'slrn_multijob',
- name = 'Employment',
- description = 'Employment application',
- defaultApp = true,
- developer = 'solareon.',
- ui = 'slrn_multijob/ui/index.html',
- icon = 'https://cfx-nui-slrn_multijob/ui/assets/icon.png',
- })
+JOBS = GetJobs()
- if not added then
- print('Could not add app:', errorMessage)
- end
-end
CreateThread(function()
while GetResourceState('lb-phone') ~= 'started' do
Wait(500)
end
+ local function AddApp()
+ local added, errorMessage = exports['lb-phone']:AddCustomApp({
+ identifier = identifier,
+ name = 'Employment',
+ description = 'Manage your employment',
+ developer = 'solareon.',
+ defaultApp = true,
+ ui = GetCurrentResourceName() .. '/ui/dist/index.html',
+ icon = 'https://cfx-nui-' .. GetCurrentResourceName() .. '/ui/dist/icon.png',
+ })
+
+ if not added then
+ print('Could not add app:', errorMessage)
+ end
+ end
+
AddApp()
-end)
+ AddEventHandler('onResourceStart', function(resource)
+ if resource == 'lb-phone' or resource == GetCurrentResourceName() then
+ AddApp()
+ end
+ end)
+end)
RegisterNUICallback('getJobs', function(_, cb)
local PlayerData = QBX.PlayerData
@@ -54,6 +62,7 @@ RegisterNUICallback('toggleDuty', function(_, cb)
end)
RegisterNUICallback('removeJob', function(job, cb)
+ TriggerServerEvent('slrn_multijob:server:deleteJob', job)
lib.callback('slrn_multijob:server:deleteJob', false, function()
cb(true)
exports["lb-phone"]:SendCustomAppMessage('slrn_multijob', { action = 'update-jobs' })
@@ -69,10 +78,4 @@ end)
RegisterNetEvent('QBCore:Client:OnJobUpdate', function()
exports["lb-phone"]:SendCustomAppMessage('slrn_multijob', { action = 'update-jobs' })
-end)
-
-AddEventHandler('onResourceStart', function(resource)
- if resource == 'lb-phone' then
- AddApp()
- end
end)
\ No newline at end of file
diff --git a/config.lua b/config.lua
new file mode 100644
index 0000000..63760aa
--- /dev/null
+++ b/config.lua
@@ -0,0 +1,3 @@
+return {
+ MaxJobs = 3, -- Maximum amount of jobs a player can have. Does not apply to QBox.
+}
\ No newline at end of file
diff --git a/fxmanifest.lua b/fxmanifest.lua
index f362dae..0a62ba5 100644
--- a/fxmanifest.lua
+++ b/fxmanifest.lua
@@ -4,28 +4,29 @@ game 'gta5'
lua54 'yes'
title 'SLRN Multijob'
-description 'QBX_Core multijob application for LB-Phone'
+description 'Multijob application for LB-Phone'
author 'solareon.'
version '1.0.2'
shared_scripts {
- '@ox_lib/init.lua'
+ '@ox_lib/init.lua',
+ 'bridge/*.lua'
}
client_scripts {
- '@qbx_core/modules/playerdata.lua',
- 'client/cl_main.lua',
+ 'client/main.lua',
}
server_scripts {
- 'server/sv_main.lua',
+ '@oxmysql/lib/MySQL.lua',
+ 'server/main.lua',
}
files {
'ui/**/*'
}
-ui_page 'ui/index.html'
+ui_page 'ui/dist/index.html'
-dependency 'qbx_core'
+dependency 'ox_lib'
dependency 'lb-phone'
\ No newline at end of file
diff --git a/server/main.lua b/server/main.lua
new file mode 100644
index 0000000..ca0972e
--- /dev/null
+++ b/server/main.lua
@@ -0,0 +1,38 @@
+lib.versionCheck('solareon/slrn_multijob')
+
+if GetCurrentResourceName() ~= 'slrn_multijob' then
+ lib.print.error('The resource needs to be named ^5slrn_multijob^7.')
+ return
+end
+
+RegisterNetEvent('slrn_multijob:server:changeJob', function(job)
+ local src = source
+ if CheckCurrentJob(src, job) then
+ Notify(src, 'Your current job is already set to this.', 'error')
+ return
+ end
+
+ if not JOBS[job] then
+ Notify(src, 'Invalid job.', 'error')
+ return
+ end
+
+ if not CanSetJob(src, job) then return end
+
+ SetPlayerJob(src, job)
+ Notify(src, ('Your job is now: %s'):format(JOBS[job].label))
+ SetPlayerDuty(false)
+ return true
+end)
+
+RegisterNetEvent('slrn_multijob:server:deleteJob', function(job)
+ local src = source
+
+ if not JOBS[job] then
+ Notify(src, 'Invalid job.', 'error')
+ return
+ end
+
+ RemovePlayerFromJob(src, job)
+ Notify(src, ('You deleted %s job from your menu.'):format(JOBS[job].label))
+end)
diff --git a/server/sv_main.lua b/server/sv_main.lua
deleted file mode 100644
index c73ff57..0000000
--- a/server/sv_main.lua
+++ /dev/null
@@ -1,57 +0,0 @@
-lib.versionCheck('solareon/slrn_multijob')
-
-if not lib.checkDependency('qbx_core', '1.7.0') then error() end
-
-if GetCurrentResourceName() ~= 'slrn_multijob' then
- lib.print.error('The resource needs to be named ^5slrn_multijob^7.')
- return
-end
-
-local function canSetJob(player, jobName)
- local jobs = player.PlayerData.jobs
- for job, _ in pairs(jobs) do
- if job == jobName then
- return true
- end
- end
- return false
-end
-
-lib.callback.register('slrn_multijob:server:changeJob', function(source, job)
- local player = exports.qbx_core:GetPlayer(source)
-
- if player.PlayerData.job.name == job then
- exports.qbx_core:Notify(source, 'Your current job is already set to this.', 'error')
- return
- end
-
- local jobInfo = exports.qbx_core:GetJob(job)
- if not jobInfo then
- exports.qbx_core:Notify(source, 'Invalid job.', 'error')
- return
- end
-
- local cid = player.PlayerData.citizenid
- local canSet = canSetJob(player, job)
-
- if not canSet then return end
-
- exports.qbx_core:SetPlayerPrimaryJob(cid, job)
- exports.qbx_core:Notify(source, ('Your job is now: %s'):format(jobInfo.label))
- player.Functions.SetJobDuty(false)
- return true
-end)
-
-lib.callback.register('slrn_multijob:server:deleteJob', function(source, job)
- local player = exports.qbx_core:GetPlayer(source)
- local jobInfo = exports.qbx_core:GetJob(job)
-
- if not jobInfo then
- exports.qbx_core:Notify(source, 'Invalid job.', 'error')
- return
- end
-
- exports.qbx_core:RemovePlayerFromJob(player.PlayerData.citizenid, job)
- exports.qbx_core:Notify(source, ('You deleted %s job from your menu.'):format(jobInfo.label))
- return true
-end)
diff --git a/ui/.gitignore b/ui/.gitignore
new file mode 100644
index 0000000..9e2e4d1
--- /dev/null
+++ b/ui/.gitignore
@@ -0,0 +1,22 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+dist
\ No newline at end of file
diff --git a/ui/dev.js b/ui/dev.js
deleted file mode 100644
index c4159ad..0000000
--- a/ui/dev.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// You can ignore this file. All it does is make the UI work on your browser.
-
-window.addEventListener("load", () => {
- if (window.invokeNative) {
- const phoneWrapper = document.getElementById("phone-wrapper");
- const app = phoneWrapper.querySelector(".app");
- phoneWrapper.parentNode.insertBefore(app, phoneWrapper);
- phoneWrapper.parentNode.removeChild(phoneWrapper);
- return;
- };
-
- document.getElementById("phone-wrapper").style.display = "block";
- document.body.style.visibility = "visible";
-
- function center() {
- document.getElementById("phone-wrapper").style.scale = window.innerWidth/1920;
- document.getElementById("phone-wrapper").style.marginTop = window.innerHeight/2 - 960/2 + "px";
- document.getElementById("phone-wrapper").style.marginLeft = window.innerWidth/2 - 540/2 + "px";
- }
-
- center();
- window.addEventListener("resize", center);
-})
\ No newline at end of file
diff --git a/ui/index.html b/ui/index.html
index d0f40c2..1bdb4a3 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -1,30 +1,19 @@
-
+
- Employment App
-
+
+
+
+ SLRN Multijob
-
+
+
+
-
-
-
-
-
-
+
+
+
diff --git a/ui/package.json b/ui/package.json
new file mode 100644
index 0000000..42ec520
--- /dev/null
+++ b/ui/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "slrn_groups",
+ "version": "2.0.0",
+ "private": true,
+ "homepage": "./",
+ "dependencies": {
+ "@fortawesome/free-solid-svg-icons": "^6.5.2",
+ "@fortawesome/react-fontawesome": "^0.2.2",
+ "@testing-library/jest-dom": "^5.17.0",
+ "@testing-library/react": "^13.4.0",
+ "@testing-library/user-event": "^13.5.0",
+ "@vitejs/plugin-react": "^4.3.1",
+ "clsx": "^2.1.1",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "tw-colors": "^3.3.1",
+ "vite": "^5.3.1",
+ "zustand": "^4.5.2"
+ },
+ "scripts": {
+ "start": "vite",
+ "start:game": "vite build --watch",
+ "dev": "vite dev",
+ "build": "vite build",
+ "serve": "vite preview"
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ]
+ },
+ "devDependencies": {
+ "autoprefixer": "^10.4.19",
+ "postcss": "^8.4.38",
+ "tailwindcss": "^3.4.4"
+ }
+}
diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
new file mode 100644
index 0000000..2a2ce9b
--- /dev/null
+++ b/ui/pnpm-lock.yaml
@@ -0,0 +1,2877 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@fortawesome/free-solid-svg-icons':
+ specifier: ^6.5.2
+ version: 6.5.2
+ '@fortawesome/react-fontawesome':
+ specifier: ^0.2.2
+ version: 0.2.2(@fortawesome/fontawesome-svg-core@6.5.2)(react@18.3.1)
+ '@testing-library/jest-dom':
+ specifier: ^5.17.0
+ version: 5.17.0
+ '@testing-library/react':
+ specifier: ^13.4.0
+ version: 13.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@testing-library/user-event':
+ specifier: ^13.5.0
+ version: 13.5.0(@testing-library/dom@8.20.1)
+ '@vitejs/plugin-react':
+ specifier: ^4.3.1
+ version: 4.3.1(vite@5.3.1(@types/node@20.14.8))
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ react:
+ specifier: ^18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
+ tw-colors:
+ specifier: ^3.3.1
+ version: 3.3.1(tailwindcss@3.4.4)
+ vite:
+ specifier: ^5.3.1
+ version: 5.3.1(@types/node@20.14.8)
+ zustand:
+ specifier: ^4.5.2
+ version: 4.5.2(@types/react@18.3.3)(react@18.3.1)
+ devDependencies:
+ autoprefixer:
+ specifier: ^10.4.19
+ version: 10.4.19(postcss@8.4.38)
+ postcss:
+ specifier: ^8.4.38
+ version: 8.4.38
+ tailwindcss:
+ specifier: ^3.4.4
+ version: 3.4.4
+
+packages:
+
+ '@adobe/css-tools@4.4.0':
+ resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==}
+
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ '@ampproject/remapping@2.3.0':
+ resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+ engines: {node: '>=6.0.0'}
+
+ '@babel/code-frame@7.24.7':
+ resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/compat-data@7.24.7':
+ resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.24.7':
+ resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.24.7':
+ resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.24.7':
+ resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-environment-visitor@7.24.7':
+ resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-function-name@7.24.7':
+ resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-hoist-variables@7.24.7':
+ resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.24.7':
+ resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.24.7':
+ resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-plugin-utils@7.24.7':
+ resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-simple-access@7.24.7':
+ resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-split-export-declaration@7.24.7':
+ resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.24.7':
+ resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.24.7':
+ resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-option@7.24.7':
+ resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.24.7':
+ resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/highlight@7.24.7':
+ resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.24.7':
+ resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/plugin-transform-react-jsx-self@7.24.7':
+ resolution: {integrity: sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-transform-react-jsx-source@7.24.7':
+ resolution: {integrity: sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/runtime@7.24.7':
+ resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/template@7.24.7':
+ resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.24.7':
+ resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.24.7':
+ resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
+ '@fortawesome/fontawesome-common-types@6.5.2':
+ resolution: {integrity: sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==}
+ engines: {node: '>=6'}
+
+ '@fortawesome/fontawesome-svg-core@6.5.2':
+ resolution: {integrity: sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==}
+ engines: {node: '>=6'}
+
+ '@fortawesome/free-solid-svg-icons@6.5.2':
+ resolution: {integrity: sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==}
+ engines: {node: '>=6'}
+
+ '@fortawesome/react-fontawesome@0.2.2':
+ resolution: {integrity: sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==}
+ peerDependencies:
+ '@fortawesome/fontawesome-svg-core': ~1 || ~6
+ react: '>=16.3'
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@jest/expect-utils@29.7.0':
+ resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/schemas@29.6.3':
+ resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/types@29.6.3':
+ resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jridgewell/gen-mapping@0.3.5':
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.4.15':
+ resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
+ '@rollup/rollup-android-arm-eabi@4.18.0':
+ resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.18.0':
+ resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.18.0':
+ resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.18.0':
+ resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.18.0':
+ resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.18.0':
+ resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.18.0':
+ resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.18.0':
+ resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
+ resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.18.0':
+ resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.18.0':
+ resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.18.0':
+ resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.18.0':
+ resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.18.0':
+ resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.18.0':
+ resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.18.0':
+ resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==}
+ cpu: [x64]
+ os: [win32]
+
+ '@sinclair/typebox@0.27.8':
+ resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
+
+ '@testing-library/dom@8.20.1':
+ resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==}
+ engines: {node: '>=12'}
+
+ '@testing-library/jest-dom@5.17.0':
+ resolution: {integrity: sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==}
+ engines: {node: '>=8', npm: '>=6', yarn: '>=1'}
+
+ '@testing-library/react@13.4.0':
+ resolution: {integrity: sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==}
+ engines: {node: '>=12'}
+ peerDependencies:
+ react: ^18.0.0
+ react-dom: ^18.0.0
+
+ '@testing-library/user-event@13.5.0':
+ resolution: {integrity: sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==}
+ engines: {node: '>=10', npm: '>=6'}
+ peerDependencies:
+ '@testing-library/dom': '>=7.21.4'
+
+ '@types/aria-query@5.0.4':
+ resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
+
+ '@types/babel__core@7.20.5':
+ resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
+
+ '@types/babel__generator@7.6.8':
+ resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==}
+
+ '@types/babel__template@7.4.4':
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+
+ '@types/babel__traverse@7.20.6':
+ resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
+
+ '@types/estree@1.0.5':
+ resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
+
+ '@types/istanbul-lib-coverage@2.0.6':
+ resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
+
+ '@types/istanbul-lib-report@3.0.3':
+ resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==}
+
+ '@types/istanbul-reports@3.0.4':
+ resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
+
+ '@types/jest@29.5.12':
+ resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==}
+
+ '@types/node@20.14.8':
+ resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==}
+
+ '@types/prop-types@15.7.12':
+ resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
+
+ '@types/react-dom@18.3.0':
+ resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
+
+ '@types/react@18.3.3':
+ resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==}
+
+ '@types/stack-utils@2.0.3':
+ resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
+
+ '@types/testing-library__jest-dom@5.14.9':
+ resolution: {integrity: sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==}
+
+ '@types/yargs-parser@21.0.3':
+ resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
+
+ '@types/yargs@17.0.32':
+ resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==}
+
+ '@vitejs/plugin-react@4.3.1':
+ resolution: {integrity: sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^4.2.0 || ^5.0.0
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.0.1:
+ resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
+ engines: {node: '>=12'}
+
+ ansi-styles@3.2.1:
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+ engines: {node: '>=4'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@5.2.0:
+ resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
+ engines: {node: '>=10'}
+
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ aria-query@5.1.3:
+ resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==}
+
+ aria-query@5.3.0:
+ resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
+
+ array-buffer-byte-length@1.0.1:
+ resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
+ engines: {node: '>= 0.4'}
+
+ autoprefixer@10.4.19:
+ resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
+ available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+ engines: {node: '>= 0.4'}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.23.1:
+ resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ call-bind@1.0.7:
+ resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
+ engines: {node: '>= 0.4'}
+
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ caniuse-lite@1.0.30001636:
+ resolution: {integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==}
+
+ chalk@2.4.2:
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+ engines: {node: '>=4'}
+
+ chalk@3.0.0:
+ resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
+ engines: {node: '>=8'}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ ci-info@3.9.0:
+ resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
+ engines: {node: '>=8'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ color-convert@1.9.3:
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.3:
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ color-string@1.9.1:
+ resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+
+ color@4.2.3:
+ resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
+ engines: {node: '>=12.5.0'}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+
+ css.escape@1.5.1:
+ resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ debug@4.3.5:
+ resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ deep-equal@2.2.3:
+ resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==}
+ engines: {node: '>= 0.4'}
+
+ define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+
+ define-properties@1.2.1:
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+ engines: {node: '>= 0.4'}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ diff-sequences@29.6.3:
+ resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ dom-accessibility-api@0.5.16:
+ resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ electron-to-chromium@1.4.811:
+ resolution: {integrity: sha512-CDyzcJ5XW78SHzsIOdn27z8J4ist8eaFLhdto2hSMSJQgsiwvbv2fbizcKUICryw1Wii1TI/FEkvzvJsR3awrA==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ es-define-property@1.0.0:
+ resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-get-iterator@1.1.3:
+ resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==}
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ escalade@3.1.2:
+ resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@1.0.5:
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+ engines: {node: '>=0.8.0'}
+
+ escape-string-regexp@2.0.0:
+ resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
+ engines: {node: '>=8'}
+
+ expect@29.7.0:
+ resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+ engines: {node: '>=8.6.0'}
+
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ flat@5.0.2:
+ resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+ hasBin: true
+
+ for-each@0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+
+ foreground-child@3.2.1:
+ resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==}
+ engines: {node: '>=14'}
+
+ fraction.js@4.3.7:
+ resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-intrinsic@1.2.4:
+ resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
+ engines: {node: '>= 0.4'}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob@10.4.2:
+ resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==}
+ engines: {node: '>=16 || 14 >=14.18'}
+ hasBin: true
+
+ globals@11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+
+ gopd@1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ has-bigints@1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+
+ has-flag@3.0.0:
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+ engines: {node: '>=4'}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+
+ has-proto@1.0.3:
+ resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ indent-string@4.0.0:
+ resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
+ engines: {node: '>=8'}
+
+ internal-slot@1.0.7:
+ resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
+ engines: {node: '>= 0.4'}
+
+ is-arguments@1.1.1:
+ resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
+ engines: {node: '>= 0.4'}
+
+ is-array-buffer@3.0.4:
+ resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
+ engines: {node: '>= 0.4'}
+
+ is-arrayish@0.3.2:
+ resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+
+ is-bigint@1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-boolean-object@1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+
+ is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+
+ is-core-module@2.14.0:
+ resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==}
+ engines: {node: '>= 0.4'}
+
+ is-date-object@1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-map@2.0.3:
+ resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
+ engines: {node: '>= 0.4'}
+
+ is-number-object@1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-regex@1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+
+ is-set@2.0.3:
+ resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
+ engines: {node: '>= 0.4'}
+
+ is-shared-array-buffer@1.0.3:
+ resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==}
+ engines: {node: '>= 0.4'}
+
+ is-string@1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+
+ is-symbol@1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+
+ is-weakmap@2.0.2:
+ resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
+ engines: {node: '>= 0.4'}
+
+ is-weakset@2.0.3:
+ resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==}
+ engines: {node: '>= 0.4'}
+
+ isarray@2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jackspeak@3.4.0:
+ resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==}
+ engines: {node: '>=14'}
+
+ jest-diff@29.7.0:
+ resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-get-type@29.6.3:
+ resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-matcher-utils@29.7.0:
+ resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-message-util@29.7.0:
+ resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-util@29.7.0:
+ resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jiti@1.21.6:
+ resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
+ hasBin: true
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ jsesc@2.5.2:
+ resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ lilconfig@2.1.0:
+ resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+ engines: {node: '>=10'}
+
+ lilconfig@3.1.2:
+ resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ lodash.foreach@4.5.0:
+ resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==}
+
+ lodash@4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
+ lru-cache@10.2.2:
+ resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==}
+ engines: {node: 14 || >=16.14}
+
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
+ lz-string@1.5.0:
+ resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
+ hasBin: true
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.7:
+ resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
+ engines: {node: '>=8.6'}
+
+ min-indent@1.0.1:
+ resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
+ engines: {node: '>=4'}
+
+ minimatch@9.0.4:
+ resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ ms@2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ nanoid@3.3.7:
+ resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ node-releases@2.0.14:
+ resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ normalize-range@0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
+ object-inspect@1.13.2:
+ resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
+ engines: {node: '>= 0.4'}
+
+ object-is@1.1.6:
+ resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==}
+ engines: {node: '>= 0.4'}
+
+ object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+
+ object.assign@4.1.5:
+ resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
+ engines: {node: '>= 0.4'}
+
+ package-json-from-dist@1.0.0:
+ resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ picocolors@1.0.1:
+ resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
+ pirates@4.0.6:
+ resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+ engines: {node: '>= 6'}
+
+ possible-typed-array-names@1.0.0:
+ resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
+ engines: {node: '>= 0.4'}
+
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.0.1:
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
+ postcss-load-config@4.0.2:
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+
+ postcss-nested@6.0.1:
+ resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.0:
+ resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.38:
+ resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ pretty-format@27.5.1:
+ resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
+ engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+
+ pretty-format@29.7.0:
+ resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ prop-types@15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ react-dom@18.3.1:
+ resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
+ peerDependencies:
+ react: ^18.3.1
+
+ react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+
+ react-is@17.0.2:
+ resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+
+ react-is@18.3.1:
+ resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
+
+ react-refresh@0.14.2:
+ resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
+ engines: {node: '>=0.10.0'}
+
+ react@18.3.1:
+ resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
+ engines: {node: '>=0.10.0'}
+
+ read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ redent@3.0.0:
+ resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
+ engines: {node: '>=8'}
+
+ regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+
+ regexp.prototype.flags@1.5.2:
+ resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
+ engines: {node: '>= 0.4'}
+
+ resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rollup@4.18.0:
+ resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ scheduler@0.23.2:
+ resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+
+ set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+ engines: {node: '>= 0.4'}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ side-channel@1.0.6:
+ resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
+ engines: {node: '>= 0.4'}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ simple-swizzle@0.2.2:
+ resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+
+ slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+
+ source-map-js@1.2.0:
+ resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
+ engines: {node: '>=0.10.0'}
+
+ stack-utils@2.0.6:
+ resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
+ engines: {node: '>=10'}
+
+ stop-iteration-iterator@1.0.0:
+ resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
+ engines: {node: '>= 0.4'}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ strip-indent@3.0.0:
+ resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
+ engines: {node: '>=8'}
+
+ sucrase@3.35.0:
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ supports-color@5.5.0:
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+ engines: {node: '>=4'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ tailwindcss@3.4.4:
+ resolution: {integrity: sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ to-fast-properties@2.0.0:
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+ engines: {node: '>=4'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tw-colors@3.3.1:
+ resolution: {integrity: sha512-PH6NShNtDzPCm6zjl0SZe3kmdYSfDS7Sk4mWa9+KzaeSH1ZmpLRrBjZoBJKaFcDB3o7iuFPPg9+HtW05pGPQyQ==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0'
+
+ undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
+ update-browserslist-db@1.0.16:
+ resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ use-sync-external-store@1.2.0:
+ resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ vite@5.3.1:
+ resolution: {integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ which-boxed-primitive@1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+
+ which-collection@1.0.2:
+ resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
+ engines: {node: '>= 0.4'}
+
+ which-typed-array@1.1.15:
+ resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
+ engines: {node: '>= 0.4'}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+ yaml@2.4.5:
+ resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+ zustand@4.5.2:
+ resolution: {integrity: sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==}
+ engines: {node: '>=12.7.0'}
+ peerDependencies:
+ '@types/react': '>=16.8'
+ immer: '>=9.0.6'
+ react: '>=16.8'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ immer:
+ optional: true
+ react:
+ optional: true
+
+snapshots:
+
+ '@adobe/css-tools@4.4.0': {}
+
+ '@alloc/quick-lru@5.2.0': {}
+
+ '@ampproject/remapping@2.3.0':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@babel/code-frame@7.24.7':
+ dependencies:
+ '@babel/highlight': 7.24.7
+ picocolors: 1.0.1
+
+ '@babel/compat-data@7.24.7': {}
+
+ '@babel/core@7.24.7':
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@babel/code-frame': 7.24.7
+ '@babel/generator': 7.24.7
+ '@babel/helper-compilation-targets': 7.24.7
+ '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7)
+ '@babel/helpers': 7.24.7
+ '@babel/parser': 7.24.7
+ '@babel/template': 7.24.7
+ '@babel/traverse': 7.24.7
+ '@babel/types': 7.24.7
+ convert-source-map: 2.0.0
+ debug: 4.3.5
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/generator@7.24.7':
+ dependencies:
+ '@babel/types': 7.24.7
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+ jsesc: 2.5.2
+
+ '@babel/helper-compilation-targets@7.24.7':
+ dependencies:
+ '@babel/compat-data': 7.24.7
+ '@babel/helper-validator-option': 7.24.7
+ browserslist: 4.23.1
+ lru-cache: 5.1.1
+ semver: 6.3.1
+
+ '@babel/helper-environment-visitor@7.24.7':
+ dependencies:
+ '@babel/types': 7.24.7
+
+ '@babel/helper-function-name@7.24.7':
+ dependencies:
+ '@babel/template': 7.24.7
+ '@babel/types': 7.24.7
+
+ '@babel/helper-hoist-variables@7.24.7':
+ dependencies:
+ '@babel/types': 7.24.7
+
+ '@babel/helper-module-imports@7.24.7':
+ dependencies:
+ '@babel/traverse': 7.24.7
+ '@babel/types': 7.24.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7)':
+ dependencies:
+ '@babel/core': 7.24.7
+ '@babel/helper-environment-visitor': 7.24.7
+ '@babel/helper-module-imports': 7.24.7
+ '@babel/helper-simple-access': 7.24.7
+ '@babel/helper-split-export-declaration': 7.24.7
+ '@babel/helper-validator-identifier': 7.24.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-plugin-utils@7.24.7': {}
+
+ '@babel/helper-simple-access@7.24.7':
+ dependencies:
+ '@babel/traverse': 7.24.7
+ '@babel/types': 7.24.7
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-split-export-declaration@7.24.7':
+ dependencies:
+ '@babel/types': 7.24.7
+
+ '@babel/helper-string-parser@7.24.7': {}
+
+ '@babel/helper-validator-identifier@7.24.7': {}
+
+ '@babel/helper-validator-option@7.24.7': {}
+
+ '@babel/helpers@7.24.7':
+ dependencies:
+ '@babel/template': 7.24.7
+ '@babel/types': 7.24.7
+
+ '@babel/highlight@7.24.7':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.24.7
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+ picocolors: 1.0.1
+
+ '@babel/parser@7.24.7':
+ dependencies:
+ '@babel/types': 7.24.7
+
+ '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.24.7)':
+ dependencies:
+ '@babel/core': 7.24.7
+ '@babel/helper-plugin-utils': 7.24.7
+
+ '@babel/plugin-transform-react-jsx-source@7.24.7(@babel/core@7.24.7)':
+ dependencies:
+ '@babel/core': 7.24.7
+ '@babel/helper-plugin-utils': 7.24.7
+
+ '@babel/runtime@7.24.7':
+ dependencies:
+ regenerator-runtime: 0.14.1
+
+ '@babel/template@7.24.7':
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/parser': 7.24.7
+ '@babel/types': 7.24.7
+
+ '@babel/traverse@7.24.7':
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/generator': 7.24.7
+ '@babel/helper-environment-visitor': 7.24.7
+ '@babel/helper-function-name': 7.24.7
+ '@babel/helper-hoist-variables': 7.24.7
+ '@babel/helper-split-export-declaration': 7.24.7
+ '@babel/parser': 7.24.7
+ '@babel/types': 7.24.7
+ debug: 4.3.5
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.24.7':
+ dependencies:
+ '@babel/helper-string-parser': 7.24.7
+ '@babel/helper-validator-identifier': 7.24.7
+ to-fast-properties: 2.0.0
+
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@fortawesome/fontawesome-common-types@6.5.2': {}
+
+ '@fortawesome/fontawesome-svg-core@6.5.2':
+ dependencies:
+ '@fortawesome/fontawesome-common-types': 6.5.2
+
+ '@fortawesome/free-solid-svg-icons@6.5.2':
+ dependencies:
+ '@fortawesome/fontawesome-common-types': 6.5.2
+
+ '@fortawesome/react-fontawesome@0.2.2(@fortawesome/fontawesome-svg-core@6.5.2)(react@18.3.1)':
+ dependencies:
+ '@fortawesome/fontawesome-svg-core': 6.5.2
+ prop-types: 15.8.1
+ react: 18.3.1
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@jest/expect-utils@29.7.0':
+ dependencies:
+ jest-get-type: 29.6.3
+
+ '@jest/schemas@29.6.3':
+ dependencies:
+ '@sinclair/typebox': 0.27.8
+
+ '@jest/types@29.6.3':
+ dependencies:
+ '@jest/schemas': 29.6.3
+ '@types/istanbul-lib-coverage': 2.0.6
+ '@types/istanbul-reports': 3.0.4
+ '@types/node': 20.14.8
+ '@types/yargs': 17.0.32
+ chalk: 4.1.2
+
+ '@jridgewell/gen-mapping@0.3.5':
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/set-array@1.2.1': {}
+
+ '@jridgewell/sourcemap-codec@1.4.15': {}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.4.15
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.17.1
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
+ '@rollup/rollup-android-arm-eabi@4.18.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.18.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.18.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.18.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.18.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.18.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.18.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.18.0':
+ optional: true
+
+ '@sinclair/typebox@0.27.8': {}
+
+ '@testing-library/dom@8.20.1':
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/runtime': 7.24.7
+ '@types/aria-query': 5.0.4
+ aria-query: 5.1.3
+ chalk: 4.1.2
+ dom-accessibility-api: 0.5.16
+ lz-string: 1.5.0
+ pretty-format: 27.5.1
+
+ '@testing-library/jest-dom@5.17.0':
+ dependencies:
+ '@adobe/css-tools': 4.4.0
+ '@babel/runtime': 7.24.7
+ '@types/testing-library__jest-dom': 5.14.9
+ aria-query: 5.3.0
+ chalk: 3.0.0
+ css.escape: 1.5.1
+ dom-accessibility-api: 0.5.16
+ lodash: 4.17.21
+ redent: 3.0.0
+
+ '@testing-library/react@13.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@babel/runtime': 7.24.7
+ '@testing-library/dom': 8.20.1
+ '@types/react-dom': 18.3.0
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
+ '@testing-library/user-event@13.5.0(@testing-library/dom@8.20.1)':
+ dependencies:
+ '@babel/runtime': 7.24.7
+ '@testing-library/dom': 8.20.1
+
+ '@types/aria-query@5.0.4': {}
+
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.24.7
+ '@babel/types': 7.24.7
+ '@types/babel__generator': 7.6.8
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.20.6
+
+ '@types/babel__generator@7.6.8':
+ dependencies:
+ '@babel/types': 7.24.7
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.24.7
+ '@babel/types': 7.24.7
+
+ '@types/babel__traverse@7.20.6':
+ dependencies:
+ '@babel/types': 7.24.7
+
+ '@types/estree@1.0.5': {}
+
+ '@types/istanbul-lib-coverage@2.0.6': {}
+
+ '@types/istanbul-lib-report@3.0.3':
+ dependencies:
+ '@types/istanbul-lib-coverage': 2.0.6
+
+ '@types/istanbul-reports@3.0.4':
+ dependencies:
+ '@types/istanbul-lib-report': 3.0.3
+
+ '@types/jest@29.5.12':
+ dependencies:
+ expect: 29.7.0
+ pretty-format: 29.7.0
+
+ '@types/node@20.14.8':
+ dependencies:
+ undici-types: 5.26.5
+
+ '@types/prop-types@15.7.12': {}
+
+ '@types/react-dom@18.3.0':
+ dependencies:
+ '@types/react': 18.3.3
+
+ '@types/react@18.3.3':
+ dependencies:
+ '@types/prop-types': 15.7.12
+ csstype: 3.1.3
+
+ '@types/stack-utils@2.0.3': {}
+
+ '@types/testing-library__jest-dom@5.14.9':
+ dependencies:
+ '@types/jest': 29.5.12
+
+ '@types/yargs-parser@21.0.3': {}
+
+ '@types/yargs@17.0.32':
+ dependencies:
+ '@types/yargs-parser': 21.0.3
+
+ '@vitejs/plugin-react@4.3.1(vite@5.3.1(@types/node@20.14.8))':
+ dependencies:
+ '@babel/core': 7.24.7
+ '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.24.7)
+ '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.24.7)
+ '@types/babel__core': 7.20.5
+ react-refresh: 0.14.2
+ vite: 5.3.1(@types/node@20.14.8)
+ transitivePeerDependencies:
+ - supports-color
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.0.1: {}
+
+ ansi-styles@3.2.1:
+ dependencies:
+ color-convert: 1.9.3
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ ansi-styles@5.2.0: {}
+
+ ansi-styles@6.2.1: {}
+
+ any-promise@1.3.0: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ arg@5.0.2: {}
+
+ aria-query@5.1.3:
+ dependencies:
+ deep-equal: 2.2.3
+
+ aria-query@5.3.0:
+ dependencies:
+ dequal: 2.0.3
+
+ array-buffer-byte-length@1.0.1:
+ dependencies:
+ call-bind: 1.0.7
+ is-array-buffer: 3.0.4
+
+ autoprefixer@10.4.19(postcss@8.4.38):
+ dependencies:
+ browserslist: 4.23.1
+ caniuse-lite: 1.0.30001636
+ fraction.js: 4.3.7
+ normalize-range: 0.1.2
+ picocolors: 1.0.1
+ postcss: 8.4.38
+ postcss-value-parser: 4.2.0
+
+ available-typed-arrays@1.0.7:
+ dependencies:
+ possible-typed-array-names: 1.0.0
+
+ balanced-match@1.0.2: {}
+
+ binary-extensions@2.3.0: {}
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.23.1:
+ dependencies:
+ caniuse-lite: 1.0.30001636
+ electron-to-chromium: 1.4.811
+ node-releases: 2.0.14
+ update-browserslist-db: 1.0.16(browserslist@4.23.1)
+
+ call-bind@1.0.7:
+ dependencies:
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ set-function-length: 1.2.2
+
+ camelcase-css@2.0.1: {}
+
+ caniuse-lite@1.0.30001636: {}
+
+ chalk@2.4.2:
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 5.5.0
+
+ chalk@3.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ ci-info@3.9.0: {}
+
+ clsx@2.1.1: {}
+
+ color-convert@1.9.3:
+ dependencies:
+ color-name: 1.1.3
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.3: {}
+
+ color-name@1.1.4: {}
+
+ color-string@1.9.1:
+ dependencies:
+ color-name: 1.1.4
+ simple-swizzle: 0.2.2
+
+ color@4.2.3:
+ dependencies:
+ color-convert: 2.0.1
+ color-string: 1.9.1
+
+ commander@4.1.1: {}
+
+ convert-source-map@2.0.0: {}
+
+ cross-spawn@7.0.3:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ css.escape@1.5.1: {}
+
+ cssesc@3.0.0: {}
+
+ csstype@3.1.3: {}
+
+ debug@4.3.5:
+ dependencies:
+ ms: 2.1.2
+
+ deep-equal@2.2.3:
+ dependencies:
+ array-buffer-byte-length: 1.0.1
+ call-bind: 1.0.7
+ es-get-iterator: 1.1.3
+ get-intrinsic: 1.2.4
+ is-arguments: 1.1.1
+ is-array-buffer: 3.0.4
+ is-date-object: 1.0.5
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.3
+ isarray: 2.0.5
+ object-is: 1.1.6
+ object-keys: 1.1.1
+ object.assign: 4.1.5
+ regexp.prototype.flags: 1.5.2
+ side-channel: 1.0.6
+ which-boxed-primitive: 1.0.2
+ which-collection: 1.0.2
+ which-typed-array: 1.1.15
+
+ define-data-property@1.1.4:
+ dependencies:
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ gopd: 1.0.1
+
+ define-properties@1.2.1:
+ dependencies:
+ define-data-property: 1.1.4
+ has-property-descriptors: 1.0.2
+ object-keys: 1.1.1
+
+ dequal@2.0.3: {}
+
+ didyoumean@1.2.2: {}
+
+ diff-sequences@29.6.3: {}
+
+ dlv@1.1.3: {}
+
+ dom-accessibility-api@0.5.16: {}
+
+ eastasianwidth@0.2.0: {}
+
+ electron-to-chromium@1.4.811: {}
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ es-define-property@1.0.0:
+ dependencies:
+ get-intrinsic: 1.2.4
+
+ es-errors@1.3.0: {}
+
+ es-get-iterator@1.1.3:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+ has-symbols: 1.0.3
+ is-arguments: 1.1.1
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-string: 1.0.7
+ isarray: 2.0.5
+ stop-iteration-iterator: 1.0.0
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ escalade@3.1.2: {}
+
+ escape-string-regexp@1.0.5: {}
+
+ escape-string-regexp@2.0.0: {}
+
+ expect@29.7.0:
+ dependencies:
+ '@jest/expect-utils': 29.7.0
+ jest-get-type: 29.6.3
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
+
+ fast-glob@3.3.2:
+ 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.7
+
+ fastq@1.17.1:
+ dependencies:
+ reusify: 1.0.4
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ flat@5.0.2: {}
+
+ for-each@0.3.3:
+ dependencies:
+ is-callable: 1.2.7
+
+ foreground-child@3.2.1:
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 4.1.0
+
+ fraction.js@4.3.7: {}
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ functions-have-names@1.2.3: {}
+
+ gensync@1.0.0-beta.2: {}
+
+ get-intrinsic@1.2.4:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ hasown: 2.0.2
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob@10.4.2:
+ dependencies:
+ foreground-child: 3.2.1
+ jackspeak: 3.4.0
+ minimatch: 9.0.4
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.0
+ path-scurry: 1.11.1
+
+ globals@11.12.0: {}
+
+ gopd@1.0.1:
+ dependencies:
+ get-intrinsic: 1.2.4
+
+ graceful-fs@4.2.11: {}
+
+ has-bigints@1.0.2: {}
+
+ has-flag@3.0.0: {}
+
+ has-flag@4.0.0: {}
+
+ has-property-descriptors@1.0.2:
+ dependencies:
+ es-define-property: 1.0.0
+
+ has-proto@1.0.3: {}
+
+ has-symbols@1.0.3: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.0.3
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ indent-string@4.0.0: {}
+
+ internal-slot@1.0.7:
+ dependencies:
+ es-errors: 1.3.0
+ hasown: 2.0.2
+ side-channel: 1.0.6
+
+ is-arguments@1.1.1:
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+
+ is-array-buffer@3.0.4:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+
+ is-arrayish@0.3.2: {}
+
+ is-bigint@1.0.4:
+ dependencies:
+ has-bigints: 1.0.2
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-boolean-object@1.1.2:
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+
+ is-callable@1.2.7: {}
+
+ is-core-module@2.14.0:
+ dependencies:
+ hasown: 2.0.2
+
+ is-date-object@1.0.5:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-extglob@2.1.1: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-map@2.0.3: {}
+
+ is-number-object@1.0.7:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-number@7.0.0: {}
+
+ is-regex@1.1.4:
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+
+ is-set@2.0.3: {}
+
+ is-shared-array-buffer@1.0.3:
+ dependencies:
+ call-bind: 1.0.7
+
+ is-string@1.0.7:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-symbol@1.0.4:
+ dependencies:
+ has-symbols: 1.0.3
+
+ is-weakmap@2.0.2: {}
+
+ is-weakset@2.0.3:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+
+ isarray@2.0.5: {}
+
+ isexe@2.0.0: {}
+
+ jackspeak@3.4.0:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
+ jest-diff@29.7.0:
+ dependencies:
+ chalk: 4.1.2
+ diff-sequences: 29.6.3
+ jest-get-type: 29.6.3
+ pretty-format: 29.7.0
+
+ jest-get-type@29.6.3: {}
+
+ jest-matcher-utils@29.7.0:
+ dependencies:
+ chalk: 4.1.2
+ jest-diff: 29.7.0
+ jest-get-type: 29.6.3
+ pretty-format: 29.7.0
+
+ jest-message-util@29.7.0:
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@jest/types': 29.6.3
+ '@types/stack-utils': 2.0.3
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ micromatch: 4.0.7
+ pretty-format: 29.7.0
+ slash: 3.0.0
+ stack-utils: 2.0.6
+
+ jest-util@29.7.0:
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/node': 20.14.8
+ chalk: 4.1.2
+ ci-info: 3.9.0
+ graceful-fs: 4.2.11
+ picomatch: 2.3.1
+
+ jiti@1.21.6: {}
+
+ js-tokens@4.0.0: {}
+
+ jsesc@2.5.2: {}
+
+ json5@2.2.3: {}
+
+ lilconfig@2.1.0: {}
+
+ lilconfig@3.1.2: {}
+
+ lines-and-columns@1.2.4: {}
+
+ lodash.foreach@4.5.0: {}
+
+ lodash@4.17.21: {}
+
+ loose-envify@1.4.0:
+ dependencies:
+ js-tokens: 4.0.0
+
+ lru-cache@10.2.2: {}
+
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+
+ lz-string@1.5.0: {}
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.7:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ min-indent@1.0.1: {}
+
+ minimatch@9.0.4:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minipass@7.1.2: {}
+
+ ms@2.1.2: {}
+
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
+ nanoid@3.3.7: {}
+
+ node-releases@2.0.14: {}
+
+ normalize-path@3.0.0: {}
+
+ normalize-range@0.1.2: {}
+
+ object-assign@4.1.1: {}
+
+ object-hash@3.0.0: {}
+
+ object-inspect@1.13.2: {}
+
+ object-is@1.1.6:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+
+ object-keys@1.1.1: {}
+
+ object.assign@4.1.5:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+
+ package-json-from-dist@1.0.0: {}
+
+ path-key@3.1.1: {}
+
+ path-parse@1.0.7: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.2.2
+ minipass: 7.1.2
+
+ picocolors@1.0.1: {}
+
+ picomatch@2.3.1: {}
+
+ pify@2.3.0: {}
+
+ pirates@4.0.6: {}
+
+ possible-typed-array-names@1.0.0: {}
+
+ postcss-import@15.1.0(postcss@8.4.38):
+ dependencies:
+ postcss: 8.4.38
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.8
+
+ postcss-js@4.0.1(postcss@8.4.38):
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.38
+
+ postcss-load-config@4.0.2(postcss@8.4.38):
+ dependencies:
+ lilconfig: 3.1.2
+ yaml: 2.4.5
+ optionalDependencies:
+ postcss: 8.4.38
+
+ postcss-nested@6.0.1(postcss@8.4.38):
+ dependencies:
+ postcss: 8.4.38
+ postcss-selector-parser: 6.1.0
+
+ postcss-selector-parser@6.1.0:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.4.38:
+ dependencies:
+ nanoid: 3.3.7
+ picocolors: 1.0.1
+ source-map-js: 1.2.0
+
+ pretty-format@27.5.1:
+ dependencies:
+ ansi-regex: 5.0.1
+ ansi-styles: 5.2.0
+ react-is: 17.0.2
+
+ pretty-format@29.7.0:
+ dependencies:
+ '@jest/schemas': 29.6.3
+ ansi-styles: 5.2.0
+ react-is: 18.3.1
+
+ prop-types@15.8.1:
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+
+ queue-microtask@1.2.3: {}
+
+ react-dom@18.3.1(react@18.3.1):
+ dependencies:
+ loose-envify: 1.4.0
+ react: 18.3.1
+ scheduler: 0.23.2
+
+ react-is@16.13.1: {}
+
+ react-is@17.0.2: {}
+
+ react-is@18.3.1: {}
+
+ react-refresh@0.14.2: {}
+
+ react@18.3.1:
+ dependencies:
+ loose-envify: 1.4.0
+
+ read-cache@1.0.0:
+ dependencies:
+ pify: 2.3.0
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
+ redent@3.0.0:
+ dependencies:
+ indent-string: 4.0.0
+ strip-indent: 3.0.0
+
+ regenerator-runtime@0.14.1: {}
+
+ regexp.prototype.flags@1.5.2:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-errors: 1.3.0
+ set-function-name: 2.0.2
+
+ resolve@1.22.8:
+ dependencies:
+ is-core-module: 2.14.0
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ reusify@1.0.4: {}
+
+ rollup@4.18.0:
+ dependencies:
+ '@types/estree': 1.0.5
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.18.0
+ '@rollup/rollup-android-arm64': 4.18.0
+ '@rollup/rollup-darwin-arm64': 4.18.0
+ '@rollup/rollup-darwin-x64': 4.18.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.18.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.18.0
+ '@rollup/rollup-linux-arm64-gnu': 4.18.0
+ '@rollup/rollup-linux-arm64-musl': 4.18.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.18.0
+ '@rollup/rollup-linux-s390x-gnu': 4.18.0
+ '@rollup/rollup-linux-x64-gnu': 4.18.0
+ '@rollup/rollup-linux-x64-musl': 4.18.0
+ '@rollup/rollup-win32-arm64-msvc': 4.18.0
+ '@rollup/rollup-win32-ia32-msvc': 4.18.0
+ '@rollup/rollup-win32-x64-msvc': 4.18.0
+ fsevents: 2.3.3
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ scheduler@0.23.2:
+ dependencies:
+ loose-envify: 1.4.0
+
+ semver@6.3.1: {}
+
+ set-function-length@1.2.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ gopd: 1.0.1
+ has-property-descriptors: 1.0.2
+
+ set-function-name@2.0.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ side-channel@1.0.6:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ object-inspect: 1.13.2
+
+ signal-exit@4.1.0: {}
+
+ simple-swizzle@0.2.2:
+ dependencies:
+ is-arrayish: 0.3.2
+
+ slash@3.0.0: {}
+
+ source-map-js@1.2.0: {}
+
+ stack-utils@2.0.6:
+ dependencies:
+ escape-string-regexp: 2.0.0
+
+ stop-iteration-iterator@1.0.0:
+ dependencies:
+ internal-slot: 1.0.7
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.0.1
+
+ strip-indent@3.0.0:
+ dependencies:
+ min-indent: 1.0.1
+
+ sucrase@3.35.0:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ commander: 4.1.1
+ glob: 10.4.2
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.6
+ ts-interface-checker: 0.1.13
+
+ supports-color@5.5.0:
+ dependencies:
+ has-flag: 3.0.0
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ tailwindcss@3.4.4:
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.6
+ lilconfig: 2.1.0
+ micromatch: 4.0.7
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.0.1
+ postcss: 8.4.38
+ postcss-import: 15.1.0(postcss@8.4.38)
+ postcss-js: 4.0.1(postcss@8.4.38)
+ postcss-load-config: 4.0.2(postcss@8.4.38)
+ postcss-nested: 6.0.1(postcss@8.4.38)
+ postcss-selector-parser: 6.1.0
+ resolve: 1.22.8
+ sucrase: 3.35.0
+ transitivePeerDependencies:
+ - ts-node
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
+ to-fast-properties@2.0.0: {}
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ ts-interface-checker@0.1.13: {}
+
+ tw-colors@3.3.1(tailwindcss@3.4.4):
+ dependencies:
+ color: 4.2.3
+ flat: 5.0.2
+ lodash.foreach: 4.5.0
+ tailwindcss: 3.4.4
+
+ undici-types@5.26.5: {}
+
+ update-browserslist-db@1.0.16(browserslist@4.23.1):
+ dependencies:
+ browserslist: 4.23.1
+ escalade: 3.1.2
+ picocolors: 1.0.1
+
+ use-sync-external-store@1.2.0(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+
+ util-deprecate@1.0.2: {}
+
+ vite@5.3.1(@types/node@20.14.8):
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.4.38
+ rollup: 4.18.0
+ optionalDependencies:
+ '@types/node': 20.14.8
+ fsevents: 2.3.3
+
+ which-boxed-primitive@1.0.2:
+ 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
+
+ which-collection@1.0.2:
+ dependencies:
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-weakmap: 2.0.2
+ is-weakset: 2.0.3
+
+ which-typed-array@1.1.15:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.2
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
+ yallist@3.1.1: {}
+
+ yaml@2.4.5: {}
+
+ zustand@4.5.2(@types/react@18.3.3)(react@18.3.1):
+ dependencies:
+ use-sync-external-store: 1.2.0(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.3
+ react: 18.3.1
diff --git a/ui/postcss.config.js b/ui/postcss.config.js
new file mode 100644
index 0000000..33ad091
--- /dev/null
+++ b/ui/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/ui/public/.gitkeep b/ui/public/.gitkeep
new file mode 100644
index 0000000..56a6051
--- /dev/null
+++ b/ui/public/.gitkeep
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/ui/assets/icon.png b/ui/public/icon.png
similarity index 100%
rename from ui/assets/icon.png
rename to ui/public/icon.png
diff --git a/ui/public/screenshot-dark.png b/ui/public/screenshot-dark.png
new file mode 100644
index 0000000..4e3387f
Binary files /dev/null and b/ui/public/screenshot-dark.png differ
diff --git a/ui/public/screenshot-light.png b/ui/public/screenshot-light.png
new file mode 100644
index 0000000..c93ceab
Binary files /dev/null and b/ui/public/screenshot-light.png differ
diff --git a/ui/script.js b/ui/script.js
deleted file mode 100644
index 7365863..0000000
--- a/ui/script.js
+++ /dev/null
@@ -1,96 +0,0 @@
-async function addJob(info) {
- if (info.disabled) {
- const container = document.querySelector('#activeJob-card');
- container.innerHTML = '';
-
- var status = 'Go On Duty';
- if (info.duty) {
- status = 'Go Off Duty';
- }
-
- var jobPanel = `
- ${info.title}
- ${info.description}
- ${status}
- Remove Job
`;
- $('#activeJob-card').append(jobPanel);
-
- } else {
- var jobPanel = `
-
-
${info.title}
-
${info.description}
-
Select
-
Remove Job
-
`;
-
- $('#jobs').append(jobPanel);
- }
-};
-
-async function loadJobs(jobs) {
- const elementsToRemove = document.querySelectorAll('.job-card');
- elementsToRemove.forEach(element => {
- element.remove();
- });
- jobs.sort((a, b) => {
- const titleA = a.title.toLowerCase();
- const titleB = b.title.toLowerCase();
- if (titleA < titleB) {
- return -1;
- }
- if (titleA > titleB) {
- return 1;
- }
- return 0;
- });
- for (i = 0; i < jobs.length; i++) {
- addJob(jobs[i]);
- }
-};
-
-window.addEventListener("load", () => {
- $.post('https://slrn_multijob/getJobs', JSON.stringify({}), function(data) {
- loadJobs(data);
- });
-
- $("body").on("click", ".activeJob-status", function(e) {
- e.preventDefault();
- fetchNui('toggleDuty', {});
- });
-
- $("body").on("click", ".job-status", function(e) {
- e.preventDefault();
- fetchNui('changeJob', this.dataset.job);
- });
-
- $("body").on("click", ".job-remove", function(e) {
- e.preventDefault();
- setPopUp({
- title: "Remove Job",
- description: "Remove " + this.dataset.title,
- buttons: [
- {
- title: "Cancel",
- color: "red",
- },
- {
- title: "Confirm",
- color: "green",
- cb: () => {
- fetchNui('removeJob', this.dataset.job);
- $(this).parent().fadeOut();
- }
- }
- ]
- })
- });
-});
-
-window.addEventListener("message", (event) => {
- if(event.data.action == "update-jobs") {
- $.post('https://slrn_multijob/getJobs', JSON.stringify({}), function(data) {
- loadJobs(data);
- });
- };
-});
\ No newline at end of file
diff --git a/ui/src/App.css b/ui/src/App.css
new file mode 100644
index 0000000..4d1ed36
--- /dev/null
+++ b/ui/src/App.css
@@ -0,0 +1,18 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/* Do not edit, this allows you to view changes easily in your browser */
+.dev-wrapper {
+ position: absolute;
+
+ bottom: 0;
+ top: 0;
+ left: 0;
+ right: 0;
+
+ margin: auto;
+
+ width: 29rem;
+ height: 58.5rem;
+}
diff --git a/ui/src/App.tsx b/ui/src/App.tsx
new file mode 100644
index 0000000..38f6c22
--- /dev/null
+++ b/ui/src/App.tsx
@@ -0,0 +1,122 @@
+import React, { useEffect, useRef, useState } from "react";
+import { useNuiEvent } from "./hooks/useNuiEvent";
+import "./App.css";
+
+const devMode = !window?.["invokeNative"];
+
+const App = () => {
+ const [theme, setTheme] = useState("light");
+ const appDiv = useRef(null);
+
+ const {
+ setPopUp,
+ fetchNui,
+ sendNotification,
+ getSettings,
+ onSettingsChange,
+ } = window as any;
+ const [currentPage, setCurrentPage] = useState("GroupDashboard");
+ const { inGroup, currentGroup } = useGroupStore();
+ const { playerData } = usePlayerDataStore();
+
+ useEffect(() => {
+ if (devMode) {
+ document.getElementsByTagName("html")[0].style.visibility = "visible";
+ document.getElementsByTagName("body")[0].style.visibility = "visible";
+ return;
+ } else {
+ getSettings().then((settings: any) => setTheme(settings.display.theme));
+ onSettingsChange((settings: any) => setTheme(settings.display.theme));
+ }
+ }, [theme]);
+
+ useEffect(() => {
+ if (!inGroup) {
+ setCurrentPage("GroupDashboard");
+ }
+ }, [inGroup]);
+
+ useNuiEvent("startJob", () => {
+ setCurrentPage("GroupJob");
+ });
+
+ useNuiEvent("sendNotification", (data: any) => {
+ sendNotification(data);
+ });
+
+ useNuiEvent("phoneNotification", (data: any) => {
+ setPopUp({
+ title: data.PhoneNotify.title,
+ description: data.PhoneNotify.text,
+ buttons: [
+ {
+ title: data.PhoneNotify.deny,
+ color: "red",
+ cb: () => {
+ $.post(
+ "https://slrn_groups/AnsweredNotify",
+ JSON.stringify({
+ type: "failure",
+ })
+ );
+ },
+ },
+ {
+ title: data.PhoneNotify.accept,
+ color: "blue",
+ cb: () => {
+ $.post(
+ "https://slrn_groups/AnsweredNotify",
+ JSON.stringify({
+ type: "success",
+ })
+ );
+ },
+ },
+ ],
+ });
+ });
+
+ const toggleTheme = () => {
+ setTheme(theme === "dark" ? "light" : "dark");
+ };
+
+ return (
+
+
+ {devMode && (
+
+ )}
+
+
Groups
+ {currentPage === "GroupDashboard" && (
+
+ )}
+ {currentPage === "GroupJob" && (
+
+ )}
+
+
+
+ );
+};
+
+const AppProvider: React.FC = ({ children }) => {
+ if (devMode) {
+ return (
+
+ {children}
+
+ );
+ } else return children;
+};
+
+export default App;
diff --git a/ui/src/components/ConfirmationDialog.tsx b/ui/src/components/ConfirmationDialog.tsx
new file mode 100644
index 0000000..585f29a
--- /dev/null
+++ b/ui/src/components/ConfirmationDialog.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+
+const ConfirmationDialog = ({ onClose, onConfirm, confirmation}) => {
+ return (
+
+
+
+ {confirmation.message}
+
+
+
+
+
+
+
+ );
+};
+
+export default ConfirmationDialog
\ No newline at end of file
diff --git a/ui/src/hooks/useNuiEvent.ts b/ui/src/hooks/useNuiEvent.ts
new file mode 100644
index 0000000..d5d3d9a
--- /dev/null
+++ b/ui/src/hooks/useNuiEvent.ts
@@ -0,0 +1,49 @@
+import { MutableRefObject, useEffect, useRef } from 'react';
+import { noop } from '../utils/misc';
+
+interface NuiMessageData {
+ action: string;
+ data: T;
+}
+
+type NuiHandlerSignature = (data: T) => void;
+
+/**
+ * A hook that manage events listeners for receiving data from the client scripts
+ * @param action The specific `action` that should be listened for.
+ * @param handler The callback function that will handle data relayed by this hook
+ *
+ * @example
+ * useNuiEvent<{visibility: true, wasVisible: 'something'}>('setVisible', (data) => {
+ * // whatever logic you want
+ * })
+ *
+ **/
+
+export const useNuiEvent = (
+ action: string,
+ handler: (data: T) => void,
+) => {
+ const savedHandler: MutableRefObject> = useRef(noop);
+
+ // Make sure we handle for a reactive handler
+ useEffect(() => {
+ savedHandler.current = handler;
+ }, [handler]);
+
+ useEffect(() => {
+ const eventListener = (event: MessageEvent>) => {
+ const { action: eventAction, data } = event.data;
+
+ if (savedHandler.current) {
+ if (eventAction === action) {
+ savedHandler.current(data);
+ }
+ }
+ };
+
+ window.addEventListener('message', eventListener);
+ // Remove Event Listener on component cleanup
+ return () => window.removeEventListener('message', eventListener);
+ }, [action]);
+};
diff --git a/ui/src/index.css b/ui/src/index.css
new file mode 100644
index 0000000..895fa15
--- /dev/null
+++ b/ui/src/index.css
@@ -0,0 +1,8 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+
+ box-sizing: border-box;
+ visibility: hidden; /* DO NOT CHANGE, IMPORTANT!*/
+}
diff --git a/ui/src/index.tsx b/ui/src/index.tsx
new file mode 100644
index 0000000..46cee71
--- /dev/null
+++ b/ui/src/index.tsx
@@ -0,0 +1,26 @@
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import App from './App'
+
+import './index.css'
+
+const devMode = !window?.['invokeNative']
+const root = ReactDOM.createRoot(document.getElementById('root'))
+
+if (window.name === '' || devMode) {
+ const renderApp = () => {
+ root.render(
+
+
+
+ )
+ }
+
+ if (devMode) {
+ renderApp()
+ } else {
+ window.addEventListener('message', (event) => {
+ if (event.data === 'componentsLoaded') renderApp()
+ })
+ }
+}
diff --git a/ui/src/utils/misc.ts b/ui/src/utils/misc.ts
new file mode 100644
index 0000000..f0a087d
--- /dev/null
+++ b/ui/src/utils/misc.ts
@@ -0,0 +1,6 @@
+// Will return whether the current environment is in a regular browser
+// and not CEF
+export const isEnvBrowser = (): boolean => !(window as any).invokeNative;
+
+// Basic no operation function
+export const noop = () => {};
diff --git a/ui/styles.css b/ui/styles.css
deleted file mode 100644
index bd4ab84..0000000
--- a/ui/styles.css
+++ /dev/null
@@ -1,208 +0,0 @@
-html, body {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- visibility: hidden;
-}
-
-::-webkit-scrollbar {
- display: none;
-}
-
-.app {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- background-color: black;
- font-family: 'Roboto', sans-serif;
- color: white;
- padding: 52px 30px;
- box-sizing: border-box;
- overflow: hidden;
-}
-
-.light {
- background-color: white;
- color: black;
-}
-
-.app-header {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- height: 50px;
- margin-bottom: 1rem;
-}
-
-.app-header-name {
- font-size: 30px;
- font-weight: bold;
-}
-
-.app-content {
- width: 100%;
- height: 100%;
-}
-
-#jobs {
- display: flex;
- flex-direction: column;
- height: 95%;
- gap: 1rem;
- overflow: auto;
-}
-
-.job-card {
- width: 100%;
- background-color: rgb(22, 22, 22);
- border-radius: 1rem;
- padding: 1rem;
- box-sizing: border-box;
-}
-
-.job-card-light {
- width: 100%;
- background-color: rgb(202, 202, 202);
- border-radius: 1rem;
- padding: 1rem;
- box-sizing: border-box;
-}
-
-.job-name {
- font-size: 25px;
- font-weight: bold;
- margin-bottom: 0.5rem;
-}
-
-.job-grade {
- font-size: 20px;
- margin-bottom: 0.5rem;
-}
-
-.job-status {
- margin-top: 1.5rem;
- background-color: rgb(40, 40, 40);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-.job-status-light {
- margin-top: 1.5rem;
- background-color: rgb(170, 170, 170);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-.job-remove {
- margin-top: 0.5rem;
- background-color: rgb(40, 40, 40);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-.job-remove-light {
- margin-top: 0.5rem;
- background-color: rgb(170, 170, 170);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-#activeJob-card {
- width: 100%;
- background-color: rgb(55, 55, 55);
- border-radius: 1rem;
- padding: 1rem;
- box-sizing: border-box;
-}
-
-.activeJob-card-light {
- width: 100%;
- background-color: rgb(202, 202, 202);
- border-radius: 1rem;
- padding: 1rem;
- box-sizing: border-box;
-}
-
-.activeJob-name {
- font-size: 25px;
- font-weight: bold;
- margin-bottom: 0.5rem;
-}
-
-.activeJob-grade {
- font-size: 20px;
- margin-bottom: 0.5rem;
-}
-
-.activeJob-status {
- margin-top: 1.5rem;
- background-color: rgb(40, 40, 40);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-.activeJob-status-light {
- margin-top: 1.5rem;
- background-color: rgb(170, 170, 170);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-.activeJob-remove {
- margin-top: 0.5rem;
- background-color: rgb(40, 40, 40);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-.activeJob-remove-light {
- margin-top: 0.5rem;
- background-color: rgb(170, 170, 170);
- padding: 0.8rem 0.5rem;
- border-radius: 0.5rem;
- font-size: 20px;
- cursor: pointer;
- text-align: center;
- font-weight: bold;
-}
-
-#phone-wrapper {
- display: none;
-
- position: absolute;
- top: 0;
- left: 0;
-
- width: 29rem;
- height: 58.5rem;
-}
\ No newline at end of file
diff --git a/ui/tailwind.config.js b/ui/tailwind.config.js
new file mode 100644
index 0000000..fc63ff3
--- /dev/null
+++ b/ui/tailwind.config.js
@@ -0,0 +1,38 @@
+/** @type {import('tailwindcss').Config} */
+const { createThemes } = require('tw-colors');
+module.exports = {
+ content: ["./src/**/*.{js,jsx,ts,tsx}"],
+ darkMode: ["selector", '[data-mode="dark"]'],
+ theme: {
+ fontFamily: {
+ sans: ["Graphik", "sans-serif"],
+ serif: ["Merriweather", "serif"],
+ },
+ extend: {},
+ },
+ variants: {
+ extend: {},
+ },
+ plugins: [
+ createThemes({
+ light: {
+ text: '#030704',
+ background: '#e6ebed',
+ primary: '#fff',
+ secondary: '#a7b7d7',
+ accent: '#8981c5',
+ danger: '#ff0000',
+ success: '#8981c5',
+ },
+ dark: {
+ text: '#e5e7eb',
+ background: '#0d1016',
+ primary: '#191c21',
+ secondary: '#283858',
+ accent: '#423a7e',
+ danger: '#ff0000',
+ success: '#423a7e',
+ },
+ }),
+ ],
+};
diff --git a/ui/tsconfig.json b/ui/tsconfig.json
new file mode 100644
index 0000000..6d4c715
--- /dev/null
+++ b/ui/tsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "paths": { "*": ["./*"] },
+ "types": ["vite/client"],
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": false,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "jsxImportSource": "react",
+ "noEmit": false,
+ "sourceMap": true,
+ "outDir": "../build/",
+ "experimentalDecorators": true
+ },
+ "exclude": ["node_modules"],
+ "include": ["src"]
+}
diff --git a/ui/vite.config.ts b/ui/vite.config.ts
new file mode 100644
index 0000000..4ba0865
--- /dev/null
+++ b/ui/vite.config.ts
@@ -0,0 +1,24 @@
+import react from '@vitejs/plugin-react';
+import { defineConfig } from 'vite';
+
+// https://vitejs.dev/config/
+export default defineConfig(( {command} ) => ({
+ base: command === 'build' ? '/ui/dist' : undefined,
+ define: {
+ global: 'window'
+ },
+ build: {
+ sourcemap: false
+ },
+ optimizeDeps: {
+ esbuildOptions: {
+ mainFields: ['module', 'main'],
+ resolveExtensions: ['.js', '.jsx']
+ }
+ },
+ server: {
+ port: 3000,
+ open: true
+ },
+ plugins: [react()],
+}));