14 Commits

Author SHA1 Message Date
minori 182fe350fa deps: update fastify to 5.7.4
Node.js CI / CI (pull_request) Successful in 32s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m24s
2026-02-13 07:06:27 -08:00
minori 90bf1a1ab9 deps: update fastify to 5.7.2
Node.js CI / CI (pull_request) Successful in 47s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 2m10s
2026-02-05 07:09:46 -08:00
minori 47b3eb2657 deps: update fastify to 5.7.1
Node.js CI / CI (pull_request) Successful in 31s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m30s
2026-02-04 08:32:47 -08:00
hikari 8ec8811a93 docs: update feedback section to use support forum
Node.js CI / CI (push) Successful in 25s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m28s
2026-01-26 12:37:26 -08:00
naomi 0e2293ad37 feat: automated upload of .gitea/workflows/ci.yml
Node.js CI / CI (push) Successful in 23s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 59s
2025-12-22 19:43:02 +01:00
naomi 5451460bb9 feat: automated upload of .gitea/workflows/ci.yml
Node.js CI / CI (push) Has been cancelled
Security Scan and Upload / Security & DefectDojo Upload (push) Has been cancelled
2025-12-22 19:36:29 +01:00
naomi 88f1ddc101 feat: automated upload of .gitea/workflows/ci.yml
Security Scan and Upload / Security & DefectDojo Upload (push) Has been cancelled
Node.js CI / Lint and Test (push) Has been cancelled
2025-12-22 19:26:14 +01:00
naomi 1f79e0ff95 feat: automated upload of .npmrc
Node.js CI / Lint and Test (push) Has been cancelled
Security Scan and Upload / Security & DefectDojo Upload (push) Has been cancelled
2025-12-22 19:17:02 +01:00
naomi acfacc4b41 feat: automated upload of .gitea/workflows/security.yml
Node.js CI / Lint and Test (push) Successful in 26s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 58s
2025-12-18 03:09:19 +01:00
naomi 5083390568 feat: add analytics
Node.js CI / Lint and Test (push) Successful in 41s
2025-10-08 15:44:36 -07:00
naomi 95166435e3 release: v1.0.1
Node.js CI / Lint and Test (push) Successful in 39s
2025-07-19 18:47:11 -07:00
naomi e8ec6b4ca0 fix: no await
Node.js CI / Lint and Test (push) Has been cancelled
2025-07-19 18:46:45 -07:00
naomi f4381f503c fix: instantiate server
Node.js CI / Lint and Test (push) Failing after 31s
2025-07-19 18:32:17 -07:00
naomi 833ab15515 fix: art must be under 3500 characters to comply with discord limits
Node.js CI / Lint and Test (push) Successful in 36s
2025-07-19 16:29:28 -07:00
9 changed files with 331 additions and 152 deletions
+15 -6
View File
@@ -8,22 +8,31 @@ on:
- main - main
jobs: jobs:
lint: ci:
name: Lint and Test name: CI
runs-on: ubuntu-latest
steps: steps:
- name: Checkout Source Files - name: Checkout Source Files
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Use Node.js v22 - name: Use Node.js v24
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v2 uses: pnpm/action-setup@v2
with: with:
version: 9 version: 10
- name: Ensure Dependencies are Pinned
uses: naomi-lgbt/dependency-pin-check@main
with:
language: javascript
dev-dependencies: true
peer-dependencies: true
optional-dependencies: true
- name: Install Dependencies - name: Install Dependencies
run: pnpm install run: pnpm install
@@ -35,4 +44,4 @@ jobs:
run: pnpm run build run: pnpm run build
- name: Run Tests - name: Run Tests
run: pnpm run test run: pnpm run test
+177
View File
@@ -0,0 +1,177 @@
name: Security Scan and Upload
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * 1'
workflow_dispatch:
jobs:
security-audit:
name: Security & DefectDojo Upload
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Checkout code
uses: actions/checkout@v4
# --- AUTO-SETUP PROJECT ---
- name: Ensure DefectDojo Product Exists
env:
DD_URL: ${{ secrets.DD_URL }}
DD_TOKEN: ${{ secrets.DD_TOKEN }}
PRODUCT_NAME: ${{ github.repository }}
PRODUCT_TYPE_ID: 1
run: |
sudo apt-get install jq -y > /dev/null
echo "Checking connection to $DD_URL..."
# Check if product exists - capture HTTP code to debug connection issues
RESPONSE=$(curl --write-out "%{http_code}" --silent --output /tmp/response.json \
-H "Authorization: Token $DD_TOKEN" \
"$DD_URL/api/v2/products/?name=$PRODUCT_NAME")
# If response is not 200, print error
if [ "$RESPONSE" != "200" ]; then
echo "::error::Failed to query DefectDojo. HTTP Code: $RESPONSE"
cat /tmp/response.json
exit 1
fi
COUNT=$(cat /tmp/response.json | jq -r '.count')
if [ "$COUNT" = "0" ]; then
echo "Creating product '$PRODUCT_NAME'..."
curl -s -X POST "$DD_URL/api/v2/products/" \
-H "Authorization: Token $DD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "'"$PRODUCT_NAME"'", "description": "Auto-created by Gitea Actions", "prod_type": '$PRODUCT_TYPE_ID' }'
else
echo "Product '$PRODUCT_NAME' already exists."
fi
# --- 1. TRIVY (Dependencies & Misconfig) ---
- name: Install Trivy
run: |
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy -y
- name: Run Trivy (FS Scan)
run: |
trivy fs . --scanners vuln,misconfig --format json --output trivy-results.json --exit-code 0
- name: Upload Trivy to DefectDojo
env:
DD_URL: ${{ secrets.DD_URL }}
DD_TOKEN: ${{ secrets.DD_TOKEN }}
run: |
echo "Uploading Trivy results..."
# Generate today's date in YYYY-MM-DD format
TODAY=$(date +%Y-%m-%d)
HTTP_CODE=$(curl --write-out "%{http_code}" --output response.txt --silent -X POST "$DD_URL/api/v2/import-scan/" \
-H "Authorization: Token $DD_TOKEN" \
-F "active=true" \
-F "verified=true" \
-F "scan_type=Trivy Scan" \
-F "engagement_name=CI/CD Pipeline" \
-F "product_name=${{ github.repository }}" \
-F "scan_date=$TODAY" \
-F "auto_create_context=true" \
-F "file=@trivy-results.json")
if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "201" ]]; then
echo "::error::Upload Failed with HTTP $HTTP_CODE"
echo "--- SERVER RESPONSE ---"
cat response.txt
echo "-----------------------"
exit 1
else
echo "Upload Success!"
fi
# --- 2. GITLEAKS (Secrets) ---
- name: Install Gitleaks
run: |
wget -qO gitleaks.tar.gz https://github.com/gitleaks/gitleaks/releases/download/v8.18.0/gitleaks_8.18.0_linux_x64.tar.gz
tar -xzf gitleaks.tar.gz
sudo mv gitleaks /usr/local/bin/ && chmod +x /usr/local/bin/gitleaks
- name: Run Gitleaks
run: gitleaks detect --source . -v --report-path gitleaks-results.json --report-format json --no-git || true
- name: Upload Gitleaks to DefectDojo
env:
DD_URL: ${{ secrets.DD_URL }}
DD_TOKEN: ${{ secrets.DD_TOKEN }}
run: |
echo "Uploading Gitleaks results..."
TODAY=$(date +%Y-%m-%d)
HTTP_CODE=$(curl --write-out "%{http_code}" --output response.txt --silent -X POST "$DD_URL/api/v2/import-scan/" \
-H "Authorization: Token $DD_TOKEN" \
-F "active=true" \
-F "verified=true" \
-F "scan_type=Gitleaks Scan" \
-F "engagement_name=CI/CD Pipeline" \
-F "product_name=${{ github.repository }}" \
-F "scan_date=$TODAY" \
-F "auto_create_context=true" \
-F "file=@gitleaks-results.json")
if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "201" ]]; then
echo "::error::Upload Failed with HTTP $HTTP_CODE"
echo "--- SERVER RESPONSE ---"
cat response.txt
echo "-----------------------"
exit 1
else
echo "Upload Success!"
fi
# --- 3. SEMGREP (SAST) ---
- name: Install Semgrep (via pipx)
run: |
sudo apt-get install pipx -y
pipx install semgrep
# Add pipx binary path to GITHUB_PATH so next steps can see 'semgrep'
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Run Semgrep
run: semgrep scan --config=p/security-audit --config=p/owasp-top-ten --json --output semgrep-results.json . || true
- name: Upload Semgrep to DefectDojo
env:
DD_URL: ${{ secrets.DD_URL }}
DD_TOKEN: ${{ secrets.DD_TOKEN }}
run: |
echo "Uploading Semgrep results..."
TODAY=$(date +%Y-%m-%d)
HTTP_CODE=$(curl --write-out "%{http_code}" --output response.txt --silent -X POST "$DD_URL/api/v2/import-scan/" \
-H "Authorization: Token $DD_TOKEN" \
-F "active=true" \
-F "verified=true" \
-F "scan_type=Semgrep JSON Report" \
-F "engagement_name=CI/CD Pipeline" \
-F "product_name=${{ github.repository }}" \
-F "scan_date=$TODAY" \
-F "auto_create_context=true" \
-F "file=@semgrep-results.json")
if [[ "$HTTP_CODE" != "200" && "$HTTP_CODE" != "201" ]]; then
echo "::error::Upload Failed with HTTP $HTTP_CODE"
echo "--- SERVER RESPONSE ---"
cat response.txt
echo "-----------------------"
exit 1
else
echo "Upload Success!"
fi
+25
View File
@@ -0,0 +1,25 @@
# Package Manager Configuration
# Force pnpm usage - breaks npm/yarn intentionally
node-linker=pnpm
# Security: Disable all lifecycle scripts
ignore-scripts=true
enable-pre-post-scripts=false
# Security: Require packages to be 10+ days old before installation
minimum-release-age=14400
# Security: Verify package integrity hashes
verify-store-integrity=true
# Security: Enforce strict trust policies
trust-policy=strict
# Security: Strict peer dependency resolution
strict-peer-dependencies=true
# Performance: Use symlinks for node_modules
symlink=true
# Lockfile: Ensure lockfile is not modified during install
frozen-lockfile=false
+1 -1
View File
@@ -8,7 +8,7 @@ This page is currently deployed. [Add to your Discord!](https://discord.com/oaut
## Feedback and Bugs ## Feedback and Bugs
If you have feedback or a bug report, please feel free to open a GitHub issue! If you have feedback or a bug report, please [log a ticket on our forum](https://support.nhcarrigan.com).
## Contributing ## Contributing
+4 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "chibika", "name": "chibika",
"version": "1.0.0", "version": "1.0.1",
"description": "A bot that shares ASCII art.", "description": "A bot that shares ASCII art.",
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
@@ -22,8 +22,9 @@
"vitest": "3.2.4" "vitest": "3.2.4"
}, },
"dependencies": { "dependencies": {
"@nhcarrigan/logger": "1.0.0", "@nhcarrigan/discord-analytics": "0.0.6",
"@nhcarrigan/logger": "1.1.1",
"discord.js": "14.21.0", "discord.js": "14.21.0",
"fastify": "5.4.0" "fastify": "5.7.4"
} }
} }
+82 -33
View File
@@ -8,15 +8,18 @@ importers:
.: .:
dependencies: dependencies:
'@nhcarrigan/discord-analytics':
specifier: 0.0.6
version: 0.0.6(@nhcarrigan/logger@1.1.1)(discord.js@14.21.0)
'@nhcarrigan/logger': '@nhcarrigan/logger':
specifier: 1.0.0 specifier: 1.1.1
version: 1.0.0 version: 1.1.1
discord.js: discord.js:
specifier: 14.21.0 specifier: 14.21.0
version: 14.21.0 version: 14.21.0
fastify: fastify:
specifier: 5.4.0 specifier: 5.7.4
version: 5.4.0 version: 5.7.4
devDependencies: devDependencies:
'@nhcarrigan/eslint-config': '@nhcarrigan/eslint-config':
specifier: 5.2.0 specifier: 5.2.0
@@ -293,8 +296,8 @@ packages:
resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@fastify/ajv-compiler@4.0.2': '@fastify/ajv-compiler@4.0.5':
resolution: {integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==} resolution: {integrity: sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==}
'@fastify/error@4.2.0': '@fastify/error@4.2.0':
resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==} resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==}
@@ -334,6 +337,12 @@ packages:
'@jridgewell/sourcemap-codec@1.5.4': '@jridgewell/sourcemap-codec@1.5.4':
resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==}
'@nhcarrigan/discord-analytics@0.0.6':
resolution: {integrity: sha512-Mci/zSY2nE24BM2cZx5EiYqwpRTTCBznFfs2BphejzDAaWPt1P12V5ln7OSUbFLGhvTD/Qwi0za3yPv6shQLoA==}
peerDependencies:
'@nhcarrigan/logger': '>=1.1.0-hotfix'
discord.js: ^14.0.0
'@nhcarrigan/eslint-config@5.2.0': '@nhcarrigan/eslint-config@5.2.0':
resolution: {integrity: sha512-YpTTqhviKMlRwKF+RC/GYiA5i2jTCmg8uftuiufldneNV5HMbGpTfBbV7tpa8++5mpYJc4+eZaf40QbDiz84dQ==} resolution: {integrity: sha512-YpTTqhviKMlRwKF+RC/GYiA5i2jTCmg8uftuiufldneNV5HMbGpTfBbV7tpa8++5mpYJc4+eZaf40QbDiz84dQ==}
engines: {node: '>=22', pnpm: '>=9'} engines: {node: '>=22', pnpm: '>=9'}
@@ -344,8 +353,8 @@ packages:
typescript: '>=5' typescript: '>=5'
vitest: '>=2' vitest: '>=2'
'@nhcarrigan/logger@1.0.0': '@nhcarrigan/logger@1.1.1':
resolution: {integrity: sha512-2e19Bie+ZKb6yKPKjhawqsENkhHatYkvBAmFZx9eToOXdOca+CYi51tldRMtejg6e0+4hOOf2bo5zdBQKmH0dw==} resolution: {integrity: sha512-P6OEQFHDtf6psybYGljuCxkSW6DLQCsx1aZZ3w4YKBXHBFjDbhuvpM9K1kPhVN48hakitx2WPLEoIFr6YZELYw==}
'@nhcarrigan/typescript-config@4.0.0': '@nhcarrigan/typescript-config@4.0.0':
resolution: {integrity: sha512-969HVha7A/Sg77fuMwOm6p14a+7C5iE6g55OD71srqwKIgksQl+Ex/hAI/pyzTQFDQ/FBJbpnHlR4Ov25QV/rw==} resolution: {integrity: sha512-969HVha7A/Sg77fuMwOm6p14a+7C5iE6g55OD71srqwKIgksQl+Ex/hAI/pyzTQFDQ/FBJbpnHlR4Ov25QV/rw==}
@@ -365,6 +374,9 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
'@pinojs/redact@0.4.0':
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
'@pkgr/core@0.1.2': '@pkgr/core@0.1.2':
resolution: {integrity: sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==} resolution: {integrity: sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
@@ -855,6 +867,10 @@ packages:
core-js-compat@3.44.0: core-js-compat@3.44.0:
resolution: {integrity: sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==} resolution: {integrity: sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==}
cron-parser@4.9.0:
resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==}
engines: {node: '>=12.0.0'}
cross-spawn@7.0.6: cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@@ -1131,15 +1147,11 @@ packages:
fast-querystring@1.1.2: fast-querystring@1.1.2:
resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==}
fast-redact@3.5.0:
resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==}
engines: {node: '>=6'}
fast-uri@3.0.6: fast-uri@3.0.6:
resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==}
fastify@5.4.0: fastify@5.7.4:
resolution: {integrity: sha512-I4dVlUe+WNQAhKSyv15w+dwUh2EPiEl4X2lGYMmNSgF83WzTMAPKGdWEv5tPsCQOb+SOZwz8Vlta2vF+OeDgRw==} resolution: {integrity: sha512-e6l5NsRdaEP8rdD8VR0ErJASeyaRbzXYpmkrpr2SuvuMq6Si3lvsaVy5C+7gLanEkvjpMDzBXWE5HPeb/hgTxA==}
fastq@1.19.1: fastq@1.19.1:
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
@@ -1500,6 +1512,9 @@ packages:
lodash@4.17.21: lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
long-timeout@0.1.1:
resolution: {integrity: sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==}
loose-envify@1.4.0: loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true hasBin: true
@@ -1507,6 +1522,10 @@ packages:
loupe@3.1.4: loupe@3.1.4:
resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==}
luxon@3.7.2:
resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==}
engines: {node: '>=12'}
magic-bytes.js@1.12.1: magic-bytes.js@1.12.1:
resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==} resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==}
@@ -1553,6 +1572,10 @@ packages:
node-releases@2.0.19: node-releases@2.0.19:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
node-schedule@2.1.1:
resolution: {integrity: sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==}
engines: {node: '>=6'}
normalize-package-data@2.5.0: normalize-package-data@2.5.0:
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
@@ -1665,14 +1688,14 @@ packages:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'} engines: {node: '>=12'}
pino-abstract-transport@2.0.0: pino-abstract-transport@3.0.0:
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==}
pino-std-serializers@7.0.0: pino-std-serializers@7.0.0:
resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==}
pino@9.7.0: pino@10.3.0:
resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==} resolution: {integrity: sha512-0GNPNzHXBKw6U/InGe79A3Crzyk9bcSyObF9/Gfo9DLEf5qj5RF50RSjsu0W1rZ6ZqRGdzDFCRBQvi9/rSGPtA==}
hasBin: true hasBin: true
playwright-core@1.54.1: playwright-core@1.54.1:
@@ -1882,6 +1905,9 @@ packages:
sonic-boom@4.2.0: sonic-boom@4.2.0:
resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==}
sorted-array-functions@1.3.0:
resolution: {integrity: sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==}
source-map-js@1.2.1: source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@@ -1961,8 +1987,9 @@ packages:
resolution: {integrity: sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==} resolution: {integrity: sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
thread-stream@3.1.0: thread-stream@4.0.0:
resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==}
engines: {node: '>=20'}
tinybench@2.9.0: tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
@@ -2405,7 +2432,7 @@ snapshots:
'@eslint/core': 0.15.1 '@eslint/core': 0.15.1
levn: 0.4.1 levn: 0.4.1
'@fastify/ajv-compiler@4.0.2': '@fastify/ajv-compiler@4.0.5':
dependencies: dependencies:
ajv: 8.17.1 ajv: 8.17.1
ajv-formats: 3.0.1(ajv@8.17.1) ajv-formats: 3.0.1(ajv@8.17.1)
@@ -2443,6 +2470,12 @@ snapshots:
'@jridgewell/sourcemap-codec@1.5.4': {} '@jridgewell/sourcemap-codec@1.5.4': {}
'@nhcarrigan/discord-analytics@0.0.6(@nhcarrigan/logger@1.1.1)(discord.js@14.21.0)':
dependencies:
'@nhcarrigan/logger': 1.1.1
discord.js: 14.21.0
node-schedule: 2.1.1
'@nhcarrigan/eslint-config@5.2.0(@typescript-eslint/utils@8.37.0(eslint@9.31.0)(typescript@5.8.3))(eslint@9.31.0)(playwright@1.54.1)(react@19.1.0)(typescript@5.8.3)(vitest@3.2.4(@types/node@24.0.15))': '@nhcarrigan/eslint-config@5.2.0(@typescript-eslint/utils@8.37.0(eslint@9.31.0)(typescript@5.8.3))(eslint@9.31.0)(playwright@1.54.1)(react@19.1.0)(typescript@5.8.3)(vitest@3.2.4(@types/node@24.0.15))':
dependencies: dependencies:
'@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.31.0) '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.31.0)
@@ -2472,7 +2505,7 @@ snapshots:
- eslint-import-resolver-webpack - eslint-import-resolver-webpack
- supports-color - supports-color
'@nhcarrigan/logger@1.0.0': {} '@nhcarrigan/logger@1.1.1': {}
'@nhcarrigan/typescript-config@4.0.0(typescript@5.8.3)': '@nhcarrigan/typescript-config@4.0.0(typescript@5.8.3)':
dependencies: dependencies:
@@ -2490,6 +2523,8 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5 '@nodelib/fs.scandir': 2.1.5
fastq: 1.19.1 fastq: 1.19.1
'@pinojs/redact@0.4.0': {}
'@pkgr/core@0.1.2': {} '@pkgr/core@0.1.2': {}
'@rollup/rollup-android-arm-eabi@4.45.1': '@rollup/rollup-android-arm-eabi@4.45.1':
@@ -3024,6 +3059,10 @@ snapshots:
dependencies: dependencies:
browserslist: 4.25.1 browserslist: 4.25.1
cron-parser@4.9.0:
dependencies:
luxon: 3.7.2
cross-spawn@7.0.6: cross-spawn@7.0.6:
dependencies: dependencies:
path-key: 3.1.1 path-key: 3.1.1
@@ -3491,13 +3530,11 @@ snapshots:
dependencies: dependencies:
fast-decode-uri-component: 1.0.1 fast-decode-uri-component: 1.0.1
fast-redact@3.5.0: {}
fast-uri@3.0.6: {} fast-uri@3.0.6: {}
fastify@5.4.0: fastify@5.7.4:
dependencies: dependencies:
'@fastify/ajv-compiler': 4.0.2 '@fastify/ajv-compiler': 4.0.5
'@fastify/error': 4.2.0 '@fastify/error': 4.2.0
'@fastify/fast-json-stringify-compiler': 5.0.3 '@fastify/fast-json-stringify-compiler': 5.0.3
'@fastify/proxy-addr': 5.0.0 '@fastify/proxy-addr': 5.0.0
@@ -3506,7 +3543,7 @@ snapshots:
fast-json-stringify: 6.0.1 fast-json-stringify: 6.0.1
find-my-way: 9.3.0 find-my-way: 9.3.0
light-my-request: 6.6.0 light-my-request: 6.6.0
pino: 9.7.0 pino: 10.3.0
process-warning: 5.0.0 process-warning: 5.0.0
rfdc: 1.4.1 rfdc: 1.4.1
secure-json-parse: 4.0.0 secure-json-parse: 4.0.0
@@ -3872,12 +3909,16 @@ snapshots:
lodash@4.17.21: {} lodash@4.17.21: {}
long-timeout@0.1.1: {}
loose-envify@1.4.0: loose-envify@1.4.0:
dependencies: dependencies:
js-tokens: 4.0.0 js-tokens: 4.0.0
loupe@3.1.4: {} loupe@3.1.4: {}
luxon@3.7.2: {}
magic-bytes.js@1.12.1: {} magic-bytes.js@1.12.1: {}
magic-string@0.30.17: magic-string@0.30.17:
@@ -3913,6 +3954,12 @@ snapshots:
node-releases@2.0.19: {} node-releases@2.0.19: {}
node-schedule@2.1.1:
dependencies:
cron-parser: 4.9.0
long-timeout: 0.1.1
sorted-array-functions: 1.3.0
normalize-package-data@2.5.0: normalize-package-data@2.5.0:
dependencies: dependencies:
hosted-git-info: 2.8.9 hosted-git-info: 2.8.9
@@ -4031,25 +4078,25 @@ snapshots:
picomatch@4.0.3: {} picomatch@4.0.3: {}
pino-abstract-transport@2.0.0: pino-abstract-transport@3.0.0:
dependencies: dependencies:
split2: 4.2.0 split2: 4.2.0
pino-std-serializers@7.0.0: {} pino-std-serializers@7.0.0: {}
pino@9.7.0: pino@10.3.0:
dependencies: dependencies:
'@pinojs/redact': 0.4.0
atomic-sleep: 1.0.0 atomic-sleep: 1.0.0
fast-redact: 3.5.0
on-exit-leak-free: 2.1.2 on-exit-leak-free: 2.1.2
pino-abstract-transport: 2.0.0 pino-abstract-transport: 3.0.0
pino-std-serializers: 7.0.0 pino-std-serializers: 7.0.0
process-warning: 5.0.0 process-warning: 5.0.0
quick-format-unescaped: 4.0.4 quick-format-unescaped: 4.0.4
real-require: 0.2.0 real-require: 0.2.0
safe-stable-stringify: 2.5.0 safe-stable-stringify: 2.5.0
sonic-boom: 4.2.0 sonic-boom: 4.2.0
thread-stream: 3.1.0 thread-stream: 4.0.0
playwright-core@1.54.1: {} playwright-core@1.54.1: {}
@@ -4287,6 +4334,8 @@ snapshots:
dependencies: dependencies:
atomic-sleep: 1.0.0 atomic-sleep: 1.0.0
sorted-array-functions@1.3.0: {}
source-map-js@1.2.1: {} source-map-js@1.2.1: {}
spdx-correct@3.2.0: spdx-correct@3.2.0:
@@ -4386,7 +4435,7 @@ snapshots:
'@pkgr/core': 0.1.2 '@pkgr/core': 0.1.2
tslib: 2.8.1 tslib: 2.8.1
thread-stream@3.1.0: thread-stream@4.0.0:
dependencies: dependencies:
real-require: 0.2.0 real-require: 0.2.0
-109
View File
@@ -604,61 +604,6 @@ export const anime: Array<Ascii> = [
⣿⠁⣿⠀⠀⡀⠀⣿⣿⡇⣿⣿⣿⣿⠏⠀⠀⠀⠂⢀⣼⣿⣿⣿⣿⣿⣿⠁⢀⣦⡘⢿⡏⢠⣿⡇⣴⣿⣿⣿⡦⢰⣿⣿⣿⣿⣿⣿⣿⣿⠃⣿⣿⣿⣿⣿⣿⣿⣿ ⣿⠁⣿⠀⠀⡀⠀⣿⣿⡇⣿⣿⣿⣿⠏⠀⠀⠀⠂⢀⣼⣿⣿⣿⣿⣿⣿⠁⢀⣦⡘⢿⡏⢠⣿⡇⣴⣿⣿⣿⡦⢰⣿⣿⣿⣿⣿⣿⣿⣿⠃⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣰⡏⠀⠀⡇⢰⢹⣿⡇⢻⣿⣿⡿⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⠁⡀⢿⣿⣿⣾⢁⣾⣿⡇⣿⣿⣿⣿⠁⣾⣿⣿⣿⣿⣿⣿⣿⡏⣰⣿⣿⣿⣿⣿⣿⣿⣿ ⣿⣰⡏⠀⠀⡇⢰⢹⣿⡇⢻⣿⣿⡿⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⠁⡀⢿⣿⣿⣾⢁⣾⣿⡇⣿⣿⣿⣿⠁⣾⣿⣿⣿⣿⣿⣿⣿⡏⣰⣿⣿⣿⣿⣿⣿⣿⣿
⣇⣿⠁⠀⠀⡇⠸⣸⣿⣷⠸⣿⣿⠀⠀⠀⠀⣼⠟⠙⢿⣿⣿⣿⡿⢁⣶⣿⣦⡍⠿⠇⣼⣿⣿⡃⣿⣿⣿⣿⠀⣿⣿⣿⣿⣿⣿⣿⡿⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿`, ⣇⣿⠁⠀⠀⡇⠸⣸⣿⣷⠸⣿⣿⠀⠀⠀⠀⣼⠟⠙⢿⣿⣿⣿⡿⢁⣶⣿⣦⡍⠿⠇⣼⣿⣿⡃⣿⣿⣿⣿⠀⣿⣿⣿⣿⣿⣿⣿⡿⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿`,
},
{
author: "https://emojicombos.com/anime-ascii-art",
text: `⢘⣿⣽⡿⣟⣯⢘⣯⢻⡭⢯⡝⣎⠷⣙⢮⡱⢣⡙⢦⡙⢆⠳⣌⠲⡡⢆⡑⢢⡘⣐⢂⡒⡐⢢⠐⢢⠐⢢⠐⡄⠢⡐⡀⠆⡐⠠⠐⠠⢀⠂⠄⠠⠀⠄⠠⠀⠄⠠⢀⠠⢀⠀⡀⢀⠀⡀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢘⣿⣾⣽⣟⡾⢨⡗⣯⢞⡧⣝⢎⡳⣍⠶⣩⢇⡹⢢⡙⣌⠳⣄⢣⡑⢎⠬⣁⠖⡈⢆⡔⠡⢆⡉⢆⠩⡐⢌⠰⡁⠤⣁⠒⡈⠄⠃⠌⢠⠈⠄⠡⠈⠄⠡⠈⠄⡁⠂⠠⢀⠂⠀⠄⡀⠄⠈⢀⠀⠐⠀⡀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢘⣯⣿⣞⣯⣟⢰⡻⣜⢯⡞⡼⣍⠶⣍⠞⣥⢚⢬⢣⢱⢊⠵⣈⠦⡙⣌⠲⣁⠎⣑⠢⢌⡑⢢⠘⡄⢣⠘⡄⢒⠨⡐⠄⢒⠈⡄⢉⡐⠠⠈⠄⠡⠈⠄⠡⢈⠐⡀⢁⠂⠄⠐⠈⡀⢀⠐⠈⢀⠠⠈⠀⢀⠀⠀⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠸⣯⣷⣟⡿⣞⠰⣯⡝⣮⣓⢳⢎⡽⣌⠻⣤⢋⢦⢣⢣⠚⡜⡤⢣⠱⣌⠓⣌⠲⣁⠎⡔⡨⡁⢎⠰⣁⠒⡈⠆⡡⢐⠉⡄⠒⡀⠆⠠⠑⡈⠤⠁⠌⠠⢁⠂⡐⢀⠂⠠⢈⠠⠁⡀⠄⠠⠈⠀⡀⠄⠈⠀⠀⠐⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣟⣷⣯⣿⡽⣘⢧⣛⢦⡝⣎⡳⡜⣬⠳⣌⣋⢦⢃⡇⢫⠴⣑⢣⠓⣌⠳⢌⠲⣈⠖⣠⠑⡌⢢⠑⡄⠃⡜⠠⢁⣂⣘⣠⣥⣤⣬⣤⣥⣤⣤⣥⣬⣐⣀⣂⠐⠠⠀⡁⠠⢀⠐⠀⠄⠂⡀⠁⡀⠀⠂⠁⠠⠀⠀⡀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠸⣿⢿⡿⣽⣳⠸⣏⢾⡱⢞⡥⢳⡙⢦⡛⡴⡘⠦⣍⠼⣡⠚⡤⢣⡙⢤⢋⠬⡱⠐⡬⢄⠣⡘⠄⣃⣬⣵⣶⣿⡿⠿⣿⣟⣛⣛⣿⣿⣟⣿⣻⣛⣛⣻⣿⠿⠿⣿⣶⣦⣥⣀⡂⠈⢀⠐⠀⡐⠀⠐⠀⡐⠀⠠⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠈⠉⠋⠘⠓⠉⠸⣝⠶⣹⢣⢞⡣⡝⢦⡓⣥⠫⡕⣊⠖⣡⢋⠴⢣⠜⡢⢍⡒⡡⢍⠰⢌⣢⣵⣿⡿⢟⣫⠽⣀⣾⠿⣽⠾⣽⣛⡾⢧⣟⣦⢭⣙⠯⣷⢯⡿⣟⡷⣾⣭⡽⣛⡿⣿⣦⣤⡐⠀⠐⠈⢀⠀⠄⠀⡀⠄⠂⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢀⣤⣁⣐⣀⡈⢀⣟⠺⡥⢏⢮⡱⣙⢦⡹⢤⠓⣥⢣⠚⡥⢪⡑⢣⠎⡱⠢⢌⡱⣈⣴⣿⡿⣻⣵⢾⠿⣩⣞⡷⣯⢿⣹⣟⠇⣼⣻⣟⣮⣟⣯⣟⣳⡌⠋⢿⡽⣽⣣⢿⡵⣮⣍⡳⢾⣝⡻⣷⣤⡐⠀⢀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢨⣷⣿⣿⣯⠇⣺⢜⣫⠵⣋⠶⡱⣍⠦⣓⠬⣋⡔⢣⡹⣐⠣⡜⡡⢎⠱⡑⣪⣾⣿⠟⣽⢾⡽⡾⢉⣴⣟⡾⣽⢯⣟⣷⣻⣀⡿⣷⢾⣳⣟⣮⣟⡷⣿⣧⣤⡿⣿⡽⣯⣟⣷⣻⣟⣶⡉⠟⣷⣭⣻⢷⣄⠀⠀⠐⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢘⣯⣿⡷⣿⡃⢜⣣⢎⡳⣍⢳⡱⢎⡱⢎⡱⢆⡙⢦⠱⣌⠳⢌⡱⢌⢃⣴⣿⢟⢡⡾⣽⢯⣟⢡⢾⣟⣾⣟⡿⣯⣟⣯⡟⢯⡿⣽⢯⣷⣻⢾⣽⣻⢷⣯⣷⡐⢯⣿⡓⢿⣾⣳⣟⢾⣽⣛⡉⢿⣻⣷⣝⢷⣄⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢨⣷⣿⣻⣟⡇⢸⡱⢎⡵⢎⠧⡜⢎⡱⢎⡱⢊⡝⢢⠓⣌⠲⢡⠒⣠⣿⢟⣵⢣⡾⣽⢯⡿⢂⣿⣻⣞⡿⣞⢠⣽⣟⣿⠀⣿⣻⣽⣻⢾⡽⣻⡆⣎⣟⣾⣳⡧⠸⣿⣷⡌⢷⣟⡾⣯⣞⣽⡶⣄⣿⢾⣿⣦⡝⢷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢨⣷⣿⣻⣯⠇⣸⢱⣋⠶⣩⠚⣥⢋⢖⢣⡱⢋⡜⣡⢋⠴⣉⠆⣵⡿⣫⣿⢃⣾⡝⢻⣯⣁⣾⢯⡷⣯⣻⠇⣞⡿⣾⠇⣯⡷⣟⠾⣽⢯⢿⢹⣞⢿⢸⡷⣯⢿⢠⢻⣯⣷⡈⢾⣟⣷⢰⡹⣽⣻⡘⣿⢾⣽⣻⣮⠙⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢰⡿⣟⣷⣿⡃⠴⢣⢎⡳⣡⠛⣤⢋⡜⣢⠑⢧⡘⢤⠋⡔⢂⣾⡟⣽⡿⡍⣼⡟⢰⣟⣯⣟⣿⢰⢺⡿⣽⢰⣻⣽⣿⢸⣗⡿⢯⣀⡿⣯⣟⡷⣞⣾⣻⡽⣾⠙⡆⡎⣷⣟⣧⢈⢿⡾⣏⠧⣹⢷⣧⠘⣟⡾⡝⣋⣷⡙⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢰⡿⣿⣻⣞⡇⢸⠣⣎⠵⣂⠟⡤⢓⠼⣠⠛⡤⣙⠢⢍⢂⣾⡟⣾⢯⡿⢰⣿⢡⣿⡛⢸⡽⣞⠿⣸⣿⠃⣸⣷⣻⡎⣼⡧⢃⣶⣻⣽⣳⣯⢿⡽⣞⡷⣻⡽⣶⡀⡻⡸⣽⡾⣇⣆⢿⣽⣻⣭⣟⡾⣇⢹⣻⢷⡹⡎⣷⡈⣟⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢨⣿⣟⣷⣿⡃⢌⡳⢌⠶⣉⠞⣰⢋⠖⣡⢋⡔⠢⢍⡂⣼⡟⣼⣟⣯⡇⣾⡏⡜⡍⣥⡾⣽⣻⢾⡽⣾⠀⢻⣼⢷⠇⣻⡆⣿⣳⣟⣾⣳⢯⡿⣽⢯⣻⢷⣻⢽⡇⢿⣆⢍⡛⢿⢸⡌⣷⣻⣞⡾⣽⢯⡘⣞⣿⠳⣶⢿⣧⠘⢮⢿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢨⣷⣿⣯⣷⡇⢘⢲⠩⡖⣩⠚⡤⢋⡜⢤⠣⢌⠓⠤⢰⡿⣹⣟⡾⡷⠁⣿⢠⡷⢧⢿⣻⢷⣯⢿⣽⡇⡇⡿⢋⡥⠆⠿⣇⢻⣵⣻⢾⣽⣫⢿⣽⣫⣟⣯⢷⠘⣏⢺⣿⡘⣋⣓⡎⣽⢘⡳⠟⢻⣽⣻⡅⡿⣯⣇⢹⡿⣿⣦⠈⢯⣻⡔⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠸⣷⡿⣽⡷⡇⢨⡃⠷⡘⢥⢋⡔⢣⠜⡢⡑⢊⠜⡀⣿⣇⣿⡿⡝⣰⢿⣧⢘⣿⡟⣸⢿⣯⣟⡿⠟⣀⡇⣶⣻⢶⠁⣿⣿⢈⣳⢯⠏⣾⣽⣻⢾⣳⣟⢾⣻⠌⣟⢸⣿⣇⢿⣽⡃⣿⣇⢿⣻⢿⡽⣷⡷⢸⢿⣿⡌⣿⢯⣷⡀⠈⣯⢿⡀⠠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣯⣿⢿⡽⡇⢰⡉⡖⡩⢆⠣⡜⡡⢎⠱⡈⢅⣊⣤⣭⣭⡙⡟⣸⡿⢸⡏⣎⣿⢅⢾⣟⣃⣭⡴⣿⢸⡇⡷⣯⢿⢸⣿⣿⡜⣯⢿⣆⢹⣷⣻⢯⡷⣯⢿⣽⣠⡏⣾⣿⣿⠘⢾⡇⢿⣿⡌⣿⢯⡿⣽⣻⢘⣯⡿⡇⢽⡿⣟⡇⠀⠘⣿⣷⡀⠈⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣯⣿⣟⡿⡇⢰⠱⢌⡱⢊⡑⢆⡱⢈⢆⣴⣿⣷⠀⠠⢈⢣⢰⢏⣔⣸⡃⣾⡟⢸⢺⡿⣽⡾⣟⡶⣸⣷⢹⣯⠿⢨⣿⣟⣇⢻⣻⢾⡌⣷⢿⣯⣟⣿⣻⢾⢩⡇⣿⠾⠿⠇⠺⠿⢸⣿⣧⢻⣯⣟⣷⡿⠈⣷⣿⡇⢾⣿⣿⡷⠀⠀⠸⡿⣧⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠸⢛⣡⣭⣶⣶⣦⣥⣌⡒⠡⠜⡠⢂⡁⡾⠿⠿⣿⣇⢁⠂⠌⡆⣿⡏⢻⡁⣿⡇⣾⠸⣟⣿⣽⣟⡇⣿⠟⠈⠀⠀⠀⠀⠈⠹⡊⢯⣟⡷⡸⣯⢷⣻⣶⣻⠏⣸⠰⠊⣀⣤⣤⣤⡄⣀⠈⠙⠜⣷⣿⢯⣿⢀⢻⣷⡇⢾⣟⣯⡟⠀⠀⠀⢹⣽⡄⠀⠀⠀⠀⠀⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣶⡿⠿⢛⣛⡙⠛⠻⠿⢿⣷⣮⡐⠡⠄⢻⡀⢢⠈⠿⠠⠘⣠⡟⣠⡅⣼⡇⣿⡄⣿⡎⣿⣟⣾⡽⠃⠁⣀⣄⢶⣿⠉⣿⣷⣶⣬⡈⢾⡽⣧⠸⣯⢷⣯⢏⣰⢇⣠⡾⠛⠉⠉⢠⢅⢿⣷⣆⠀⠸⣯⣿⠇⣾⢸⣿⡇⣾⣟⣿⡏⠀⠀⠀⠀⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢫⣴⡿⣟⡷⣇⢰⡶⣦⣖⣬⡙⠻⢷⣬⡀⠳⣄⢈⡠⠴⠶⡶⠶⡹⡇⢾⡇⣽⡆⣿⡧⢸⣿⡟⠀⠀⠀⠁⢰⡔⣮⠃⣿⣿⣿⣿⣿⣌⢽⣳⡇⠺⣟⡾⣏⢋⣾⣿⠁⠀⠀⠀⢀⠋⠀⣿⣿⣧⠀⠸⢣⣤⣿⢨⡷⢰⣿⢿⣿⠁⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣟⣿⡽⣟⣇⢺⣽⢷⣻⣾⣽⣣⠀⡈⢉⠓⢤⣷⣿⣧⢛⢬⢣⢱⡁⣾⣇⢸⡇⢿⣿⡆⢻⠀⢀⠰⠀⠀⠀⢉⡈⠂⢹⣿⣿⣿⣿⣿⣷⣜⡹⠧⢙⠞⣡⣿⣿⣿⡄⣄⠀⣠⣾⣷⡄⣿⣿⣿⠀⠀⣿⢸⣿⠰⢡⢻⣿⣿⠟⠀⠀⠀⠀⠀⢸⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣯⡿⣽⢿⡎⣼⢯⣟⣯⣷⣿⣽⠂⡀⠃⠌⣏⢙⠿⣿⡌⡖⢣⠆⠇⣿⣿⣂⢟⢸⣿⣿⡎⠂⠘⡌⠀⠀⢀⡼⣿⡆⣸⣿⣿⣿⣿⣿⣿⡿⣡⢛⣩⣾⣿⣿⣿⣿⣿⣜⡿⠷⠦⣙⣴⣿⣿⡿⢀⣼⣿⢸⢿⣤⣿⢸⣿⠏⠀⠀⠀⠀⠀⠀⠸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⡷⣿⢯⣟⡷⣸⡿⣞⣷⣯⣷⣻⠄⠠⡉⠄⠸⣌⡒⠭⠱⣉⠥⣪⡅⣯⣷⡿⣮⠀⢻⣾⣟⢸⣦⣑⣜⠿⣿⡿⢗⣵⣿⣿⣿⣿⣿⣿⣿⣷⣶⣿⣿⣿⣿⣏⣿⣿⣷⣝⣻⢿⡿⢿⣿⣛⣯⣿⣿⣿⣿⢸⣻⣞⣇⣘⣡⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠸⣟⣿⡿⣯⡷⣹⢿⣽⣻⡾⣿⣽⠂⠡⠐⣈⠐⡈⢉⢩⣽⣶⣿⢿⡇⣟⣯⡿⣽⣻⣟⡷⢸⢸⣿⣿⣯⣝⣛⣛⣛⣿⣽⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⣳⢯⣟⣿⡿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣤⣛⣋⣛⣳⣋⣬⣭⣬⣥⣯⡽⣬⣃⣤⣁⡀⢂⠐⠠⢸⣿⣳⣿⣻⢀⣿⣳⡿⣽⣳⢯⣟⠸⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣼⣫⣟⡾⣯⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢋⠛⡙⢋⠛⠙⠋⠛⠙⠛⠺⠙⠛⠟⠯⠛⠄⠂⠈⠐⢸⣿⣟⣾⢿⢈⣿⢿⡽⣷⢯⣟⣾⡃⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣥⣶⣶⢶⣶⢶⡖⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⡷⣯⢿⡽⣷⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠢⠑⠘⠢⢉⠬⠡⠍⣊⠑⠆⠩⠒⢌⠢⠱⡈⠆⠍⠂⢸⣿⣟⣯⣿⢸⣯⢿⡽⣯⣟⣾⣳⠇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⣷⣻⣾⣟⣾⣯⢿⡃⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⡿⣭⣟⣿⣟⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠰⡐⢂⠖⡠⢂⠔⡰⢀⠆⡒⡄⠦⢠⠒⠤⠰⡐⠤⠂⣼⣿⢯⣟⡞⣸⢯⡿⣽⣳⣟⣾⣭⡇⢘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⡿⣾⣽⣷⢿⣻⣾⣟⡇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⡿⣵⣻⣾⣻⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣶⣶⣶⡶⣶⣲⢶⣲⣦⣶⣴⣴⣦⣦⣴⣤⢦⠀⠀⠀⣿⣯⣿⣯⡇⣽⣻⢿⣽⣳⣟⣾⣳⣟⢸⢁⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⣹⣟⣾⢿⣻⣽⣾⡽⠇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣱⠇⣟⣷⣻⣼⣟⣷⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠉⢐⣶⣶⣶⣦⡏⠓⠋⠓⠛⠙⠛⠛⠙⠚⠉⠀⡐⠀⣿⣿⣷⣟⠇⣾⣽⣻⣞⣷⣻⡞⣧⣿⠸⢨⣇⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⣿⡽⣿⢯⣷⣯⡟⢸⣿⣿⣿⣿⣿⣿⣿⣿⡿⢫⡼⢯⣇⢻⣞⣷⣻⣾⣟⣯⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢌⣿⣟⣿⣾⡇⠀⡐⢀⠂⡐⠠⠀⢀⠐⠈⢀⠀⢰⣿⢿⣷⣻⢇⣿⣞⣷⣟⡾⣷⠃⡿⣟⠀⣾⡽⣧⢙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣌⠿⣝⣯⠷⢋⣴⣿⣿⣿⣿⣿⣿⣿⢟⠩⡎⢰⣟⢸⣯⢸⣟⡾⣽⣞⣯⡿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢨⣿⣾⣟⣷⡇⢀⠐⡀⢂⠄⡁⠂⠀⠠⠈⠀⡀⢼⢻⣿⣟⡿⢸⣷⣻⢾⣽⣻⣽⢂⢹⣿⡇⣯⡿⡽⢸⣷⢩⣛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣾⣿⣿⣿⣿⣿⡿⢟⣫⡵⡏⢸⣧⢈⣿⡀⣿⢸⣾⠇⣿⢯⣿⣽⣻⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢢⣿⣽⡿⣯⡇⠀⢂⠐⡀⠂⠄⡁⠀⠁⡀⠁⢀⡏⣬⣿⣿⡓⣸⣷⣻⣟⣾⣳⢿⢸⢸⣿⡇⣿⣽⡇⣻⡎⢸⣽⣻⢰⣮⡭⠟⡛⣻⣿⣿⣿⣿⣿⣿⡿⠿⠿⠿⢛⣋⣑⡆⢿⣳⣟⡗⢸⣯⣄⣿⣧⠸⢸⢾⡃⣿⣻⣯⣿⣟⣷⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠰⣿⣳⣿⢿⡇⠐⡀⠂⠄⡉⠐⠀⠀⠐⠀⡀⡼⣰⣿⣻⣽⠃⣿⣽⢷⣻⡾⣽⣿⠸⡄⣿⡆⣟⣿⢁⡷⣏⢰⣿⡉⡖⣩⡖⣿⡷⢹⣿⣿⣿⣿⣿⣿⣿⣿⣶⡄⣾⣿⡿⢋⣵⡂⢹⣿⢸⣿⡍⢿⣿⣇⢸⣿⠁⢸⣿⣻⣷⣻⣿⣻⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢘⣿⢿⣽⣟⡇⠀⠀⠁⠂⠀⠁⠀⠀⠂⠀⢠⢳⣿⣿⢯⡿⢠⣿⢾⣟⣷⣻⡽⣿⢘⡇⢿⣇⢸⡿⣬⣿⣧⢸⢯⣿⠸⣿⣧⡹⢿⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⣛⣭⣶⣿⣿⡟⢸⣷⡈⣿⣯⡌⣿⣯⢸⣿⢸⢸⣿⣽⡷⣿⣽⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢨⡿⣟⣿⣞⡇⠀⠀⡀⠄⠀⠄⠐⠀⠀⠀⢤⣿⣿⢾⣻⠇⢸⣯⢿⡾⣽⢯⡿⣽⡎⣷⢸⣿⠘⢡⣟⣿⡷⢸⣻⢯⣇⢻⣿⣿⣶⣬⣟⡛⣿⢟⣭⣭⣽⣶⣾⣿⣿⣿⣿⣿⣿⡇⡟⣾⡅⢻⣿⣷⡘⡧⢸⡏⢸⡎⣷⣿⣻⣽⡾⣷⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠰⣿⣟⡿⣾⡅⠀⠀⠀⠀⡀⠀⠀⠀⠀⢠⣾⣿⣻⣟⡿⢸⢸⣯⢿⡽⣯⢿⣽⣻⡇⣿⡈⣿⡆⢼⣟⣯⢿⡌⣟⣯⡟⢀⣿⣿⣿⣿⣿⡇⡆⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⢠⢿⣽⣻⡌⣷⡿⣷⡀⣿⢃⣿⡇⣟⣾⣻⣽⢿⣳⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢘⡷⣯⣿⢷⡃⠀⠀⠀⠁⠀⠀⠀⠀⢠⣿⣿⣳⣟⡾⢡⣿⢸⡷⣯⢿⣽⡻⣞⡷⡆⠿⢧⠹⣷⠸⣯⣟⡿⢆⣹⣤⡶⣼⣿⣿⣿⣿⣿⡇⡇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡌⣭⣚⡳⢷⡘⢟⠷⢡⡟⣸⣏⡇⢾⣳⢯⣟⣯⢿⡅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢨⣟⡷⣯⡿⡅⠀⠀⠀⠀⠀⠀⠀⢀⣿⣟⣾⣳⣭⢃⣞⡷⠈⡿⣭⣟⡾⣽⣫⢿⡅⣛⣟⡆⢿⡆⣭⡶⢞⣫⣭⣶⣇⣿⣿⣿⣿⣿⣿⡧⣿⢽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡨⣭⣛⣻⠶⡶⠟⡼⢑⣛⣻⡃⢿⣽⡻⣾⡽⣻⢳⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢠⡿⣽⢯⣷⡃⠀⠀⠀⠀⠀⠀⢀⣾⡿⣽⢞⣧⡟⣯⠞⣰⡿⡸⣳⣻⢞⡷⣯⢯⢷⢸⣿⣷⡈⣷⡰⣾⣿⣿⣿⣿⡞⢿⣿⣿⣿⣿⣿⣿⢿⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣩⣿⣿⣿⣿⣿⡟⡸⢡⣿⣿⣿⡇⣻⣞⣽⣳⠿⡝⣈⢿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢐⡿⣽⣻⢶⡃⠀⠀⠀⠀⠀⢀⣾⢯⣟⣭⡟⣮⡽⡞⣼⡿⣱⣧⡑⢯⣻⡽⣞⢯⣯⠈⣿⣿⣷⡈⢇⢹⣿⣧⢹⣇⡹⣮⡛⢿⣿⣿⣿⣿⢸⢸⣿⣿⣿⣿⣿⣿⣿⡿⢟⢡⣾⣿⡟⣸⣿⣿⣟⣀⣵⣿⣿⣿⣿⠃⡷⣞⣳⢯⠟⣰⣿⡞⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢠⣟⡷⣯⣏⡇⠀⠀⠀⠀⢀⣾⢯⣟⡞⣧⢿⣱⡛⣼⡿⣱⣿⡿⣷⡌⠳⣽⢫⣟⡞⣇⢹⣿⣿⣿⣮⡀⢻⣿⡌⣿⣷⡜⢿⣷⣭⡛⠿⣿⢸⢈⣿⣿⣿⡿⠿⣛⣭⢖⣥⣾⣿⢏⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⡸⡽⡏⠟⣠⣾⣿⣿⣿⢸⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠
⠀⠠⣟⡾⣵⢫⡆⠀⠀⠀⠀⣾⣭⣟⡮⣽⢎⡷⡓⣼⡿⣱⣟⣷⢿⣟⣿⣷⣠⠻⢼⡻⡽⡄⢿⣻⣿⣿⣿⣿⣿⣧⢹⣿⣿⣮⣙⢿⣿⣷⢣⡟⣬⣿⣧⣶⣶⠿⣫⣴⣿⣿⠟⣡⣾⣿⣿⣿⡟⢸⣿⣿⣿⣿⡿⣷⣴⣵⣶⣿⣿⣽⣿⡿⣿⡇⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠌⡀
⠀⠐⣯⣳⢏⡷⡁⠀⠀⠀⣼⡳⣽⢎⡷⣹⢎⡷⢱⣿⢣⣿⣞⡿⣯⡿⣟⣾⡟⢻⣶⡬⢉⣙⣂⣿⣿⡷⣿⣻⣿⢿⣆⠻⣿⣿⣿⣶⣍⣛⡞⡇⣿⠿⢛⣩⣶⣿⣿⣿⠟⣣⣾⣿⣿⣿⣿⣿⠇⣿⣿⣿⣿⢃⣼⣿⣿⣿⣿⡿⣿⡿⣽⡿⣟⣷⢹⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠌⡀⠀
⠀⢈⡷⣭⣻⢼⡁⠀⠀⣸⢧⡻⣵⢫⣞⡱⣫⢆⣿⡏⣾⡽⣾⣽⣳⣿⣻⣽⢰⣿⢿⢃⣿⣻⣟⣯⣷⢿⣻⣽⢯⣿⢿⣧⠘⢯⣿⣾⣻⢟⡴⣡⣵⣾⡿⣿⣿⣟⠟⣡⣾⣿⢿⣿⣻⣽⣻⣽⢰⣿⣯⣿⢂⣾⣿⢿⣿⣽⢯⣿⡷⣿⣽⣟⡿⣽⢸⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⢈⠐⠀⠀
⠀⠠⣟⢶⡹⢦⠃⠀⢰⡹⣎⢷⢣⣏⠶⣍⠇⣼⡿⣸⢷⣻⢷⣫⢷⣯⢷⡏⡴⣿⠏⡼⣟⣷⣻⢯⣟⣯⢿⣞⣯⣟⣿⣻⣷⡈⢿⣳⡇⡟⣸⣿⢿⣽⡿⠿⢙⣴⡾⣿⣽⡾⣿⣽⢯⣟⣿⡟⢸⣯⢿⢃⣾⣟⣾⡿⣾⣟⡿⣞⡿⣽⣳⣯⣟⡿⡞⣿⣇⡄⠀⠀⠀⠀⠀⠀⠀⠀⠄⡁⢂⠀⠀⠀
⠀⠐⣽⣊⠷⣍⠆⠀⣧⣛⡼⢣⠯⣜⠳⣜⢰⣿⢣⣟⣳⢯⣟⡽⣻⣞⣯⡅⣿⡝⢸⡿⣽⣳⣟⣯⣟⡾⣯⣟⡾⣽⣞⡷⣿⣽⣊⠹⡃⡇⣿⢯⠟⢓⣥⡾⣟⣷⣟⣷⢯⣿⡽⣞⣿⢯⣷⠏⣼⢿⢃⡾⣷⣻⣾⡽⣷⢯⡿⣽⣻⣽⣳⣟⡾⣽⡇⣿⣿⢡⠀⠀⠀⠀⠀⠀⠄⡁⢂⠐⠠⠀⠀⠀
⠀⠈⢶⢩⡓⢎⠆⢸⡱⣎⡵⣋⠗⣮⡙⡆⣿⡟⢮⣳⢻⡞⣭⣟⣳⢯⣾⢰⢯⠇⡿⣽⣳⢯⡾⣵⢯⣻⣵⣻⣞⡷⣽⣏⡷⣯⢯⣟⡇⡇⣿⣻⡞⣿⢾⣽⣻⠾⣽⣞⣯⢷⡿⣽⢾⣻⢾⠃⣾⣏⣸⣟⣷⣻⣼⣻⡽⣯⢟⡷⡽⣞⣧⢿⣹⣳⠇⣿⣿⢨⡀⠀⠀⠀⠀⠌⠐⡀⠂⠌⡀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣧⢓⣎⠶⢩⠞⡴⣩⢸⣿⢣⢯⡽⣳⣛⠷⡾⣭⢷⣫⢘⡯⢰⡟⣧⣟⢯⡽⣞⢯⣳⡞⡷⣞⡽⣧⢿⣹⣞⣻⡼⢃⡇⣿⣱⠿⣭⣟⡾⣽⢻⣧⡟⣞⣯⡙⣾⢯⣻⢿⡤⡝⣞⡷⣯⣞⢷⣭⢷⣻⡽⢯⣻⡽⣽⣚⡯⢷⣫⠇⣿⣿⣎⡅⠀⠀⠀⠌⠠⠁⠄⡁⠂⠄⠀⠀⠀
⠀⠀⠤⠤⡄⢆⢰⢪⡝⡬⠋⣠⢛⡴⡁⣾⡟⣬⢳⡝⣧⢟⣯⢳⡏⣯⢳⢨⠷⣲⢟⣧⢯⣏⡷⢯⣻⣵⡻⣝⡾⣵⣛⡾⣵⣫⠷⡽⣸⢃⣷⢫⣟⣳⢯⡽⣞⣻⢖⣿⣹⣞⡁⣯⣻⣝⡾⡝⢰⣏⡿⣼⣞⣻⣎⡿⣼⣝⡯⣷⣹⣞⣭⡟⣭⢷⡃⣿⣿⡇⡽⠀⠀⡈⠄⠡⢈⠐⡀⢁⠂⠀⠀⠀`,
}, },
{ {
author: "https://emojicombos.com/anime-ascii-art", author: "https://emojicombos.com/anime-ascii-art",
@@ -784,60 +729,6 @@ export const anime: Array<Ascii> = [
⣿⢡⢡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠻⣿⡇⡇⣤⣦⣄⣿⣿⣿⣿⡜⢸⣿⣿⢸⡞⣿⣿⣿⣿⣿⢿⣿⣿⣿⢸ ⣿⢡⢡⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠻⣿⡇⡇⣤⣦⣄⣿⣿⣿⣿⡜⢸⣿⣿⢸⡞⣿⣿⣿⣿⣿⢿⣿⣿⣿⢸
⣿⡌⣀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⢀⣿⣿⢡⢿⣿⣿⣿⣿⣿⣿⣧⢁⢻⣿⢸⡇⣿⣿⣿⣿⢃⣾⣿⣿⡟⣼ ⣿⡌⣀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⢀⣿⣿⢡⢿⣿⣿⣿⣿⣿⣿⣧⢁⢻⣿⢸⡇⣿⣿⣿⣿⢃⣾⣿⣿⡟⣼
⡇⡇⣿⠁⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠸⣿⣿⣿⣿⣿⣿⣿⣧⠀⠹⢸⢹⣿⣿⠿⢣⣾⣿⣿⣿⡇⢹`, ⡇⡇⣿⠁⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠸⣿⣿⣿⣿⣿⣿⣿⣧⠀⠹⢸⢹⣿⣿⠿⢣⣾⣿⣿⣿⡇⢹`,
},
{
author: "https://emojicombos.com/anime-ascii-art",
text: `⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣷⡆⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣾⣿⣷⡗⢠⣶⣾⣶⣿⣾⣷⣿⣾⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⣛⣊⣛⣛⣛⣿⣿⣿⣿⣿⣛⣛⣛⣛⣛⠛⠛⣛⣛⣫⣭⣭⣥⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⢦⣭⣭⣝⣛⣛⠛⢛⣛⣛⣛⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢟⣛⣛⣛⣛⡿⠿⠿⠿⣛⣫⣥⣶⡾⣿⢿⣻⢿⡽⣯⣿⣻⢾⡽⣯⢿⡽⣯⢿⡽⣞⣯⢿⣯⣟⣿⣻⣽⢿⣶⣬⣛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⢿⣿⡿⣿⣿⢿⡿⣿⢿⡿⣿⢿⡿⣿⢿⡿⣿⠿⣯⢿⣟⡿⣻⢯⣿⣻⡽⣿⡽⡿⣯⢿⡿⣽⢯⣶⢳⡶⡆⢼⡿⣟⡿⣯⢿⡿⣿⣻⣟⣿⣻⢷⣿⡽⣟⣯⣿⣻⣽⢷⣻⣟⡿⣽⣟⡿⣽⣻⣟⣯⣟⡿⣾⣽⢾⣟⣾⢿⣽⣻⣽⣾⣆⠉⠬⣭⡝⣯⡝⣯⢻⡝⣯⢟⡽⢯⡟⢯⡿⡽⢯⡟⣿
⣻⣽⣟⣿⣿⣯⣿⢿⣯⣿⢯⣿⢿⣯⡿⣽⣯⡿⣟⡿⣞⣿⣻⣯⢷⣻⣽⢷⣻⣽⣟⣯⡿⠽⠛⠚⣋⣋⡁⢾⣟⣿⣽⣟⣯⣟⣷⢿⣽⣾⣻⣟⣾⣻⢯⣟⣾⣽⢾⣯⣟⡾⣟⡷⣯⣟⣯⣷⣻⢾⣽⣻⣯⠘⣿⣽⡾⣟⣾⣽⣳⣟⣾⡿⣗⣄⠻⢷⣻⡽⣯⢿⣽⣫⣟⣯⣟⣯⣽⣻⢯⣟⡷
⣽⢾⣯⣿⢷⣯⡿⣿⡽⣟⣿⢯⣟⡾⣿⡽⣾⡽⣯⣟⣯⢷⡿⣽⣻⣽⢾⡻⠝⢚⣩⣤⣶⣾⢿⣿⣟⣯⠇⣹⡿⣞⣷⣯⣟⡾⣯⡿⣞⡷⣟⣾⢯⣟⣯⢿⡾⣽⣟⣾⣽⣻⢿⡽⣷⣻⣽⢾⣽⣯⣷⣟⣯⣷⡈⢷⣿⣻⣽⢾⣻⣞⣯⢿⣟⣷⣶⡉⢷⡻⣭⣟⣶⣻⣼⣳⣞⡷⣽⡞⣟⡾⣽
⣽⣻⢷⣿⣻⣽⣟⣷⢿⣻⢾⣯⢿⣽⣳⣟⣷⣻⢷⣻⣞⣯⣟⡷⠏⣩⣤⣶⣿⢿⣟⣯⡿⣞⣯⡷⡯⢋⠀⣽⢿⣽⣳⡿⣞⣿⢷⣻⣯⢿⣽⡾⣿⡽⣾⣻⣽⣻⢾⣻⣾⡽⣯⣟⣷⣻⣽⣻⣾⣽⡄⠻⢾⡽⣷⡌⢷⣻⣽⣟⣯⢿⣞⣯⣟⡾⣷⣿⡄⠻⣵⣻⢮⡷⣏⣷⡻⣞⣷⢻⡽⣽⢞
⣾⣽⣯⣿⢯⣷⢿⣞⣿⣻⣟⣾⣻⣞⣷⣻⢾⣽⢯⣷⡻⢎⣡⣶⣿⣻⢿⣽⣾⣯⢿⡽⣟⣯⢷⡟⠁⠦⡁⢾⣟⡷⣯⡟⣯⣟⣯⣷⣟⡿⣾⣽⣳⡿⣽⡷⣇⢿⣻⢷⣯⢿⣷⣻⣞⣯⣷⢝⢾⣯⢿⣷⣌⠻⣽⣷⡌⢻⣷⣻⢾⣯⣟⡷⣟⣿⣽⡾⡿⠄⠱⣯⢷⣻⡽⡾⣽⣛⡾⣯⡽⣞⣯
⢾⣳⣯⣿⣟⣯⢿⣾⣳⣟⣾⣳⣯⢿⡾⣽⣻⣞⠟⣠⣶⣿⡿⣷⣯⣿⢯⠟⣉⣴⡾⣟⣯⣟⠏⠀⣩⣶⣧⢸⣿⣻⣽⡇⣻⣽⢾⣳⣯⢿⡿⡌⣷⣻⢯⣿⣽⡈⠻⣟⣾⢿⣞⣷⣻⡽⣾⣳⣕⢍⢿⣞⣿⣧⣌⢳⣿⡄⢿⢯⡿⣞⣯⡓⣿⣳⢯⣿⢿⡞⡄⢱⢯⣗⡿⣝⣳⢯⣷⢫⣷⢻⣼
⡿⣽⣞⣿⣾⣻⡿⣾⡽⣾⢷⣯⣟⣯⢿⡳⢋⣴⣾⣟⣯⣷⣿⣿⠽⠋⢡⣾⢿⣽⣻⣽⣻⢎⡴⣾⢿⣽⣿⠘⣷⣯⣷⡇⠼⣟⣯⡿⣞⣿⣽⣷⡘⣯⣿⢾⣽⣇⠡⠙⣯⣿⣻⣞⡷⣟⣷⣻⣽⡷⣅⢝⢾⣽⣻⣦⡙⢿⡌⢻⣽⣻⣽⠃⣿⣽⣻⣾⡏⡹⡴⢀⢻⢮⣟⡽⡽⣞⣳⡟⣞⡿⣼
⣽⣻⣯⣿⡷⣿⣻⢷⣿⣻⣯⢿⣞⣯⢋⣵⣿⣻⣽⣾⠿⢙⣡⢄⡔⣴⣿⣻⢿⣾⣽⣳⣯⢾⣻⣽⡛⢰⣿⡀⣿⣳⣯⡗⢌⣿⣳⣟⣯⣟⣾⢷⣷⠘⡽⣟⣿⣾⡆⠡⠌⢷⡿⣽⣻⢯⣟⡷⣯⣫⣪⡢⡑⢝⢷⣻⢿⣄⠻⡄⢿⣽⣻⠌⣻⣞⣷⢯⣷⠁⡇⡏⡌⣟⡾⣽⣻⣭⢷⣻⡽⣞⢷
⣽⣻⡷⣿⣟⣿⣽⣿⡾⣟⣾⣟⠏⣡⣿⣽⣳⠿⢋⣡⣶⠟⣱⣿⡸⣿⡽⣿⣻⣞⡷⣟⣾⢿⣽⣻⢃⣷⢿⡇⢸⣿⣞⡇⠎⣼⡿⣽⢾⣻⡾⣿⣽⡀⡘⢿⣳⣯⣿⠆⢉⠄⠻⣿⣽⣻⣽⣻⡽⣷⣟⣿⣎⢦⠱⡹⠻⣟⣷⡄⠈⣷⣻⢨⢹⣾⣽⣻⣽⣸⢹⣰⡇⢸⡽⡾⣵⡻⣞⣧⠿⣽⣞
⣽⣻⡽⣿⣯⣿⣟⣾⣟⣿⡳⢡⣾⣿⠟⢋⣥⡾⣿⡽⢣⣾⣿⣿⣿⢆⣤⣛⡳⠿⣟⢯⣿⣟⣿⡇⣼⣯⣿⢿⠘⣷⡯⠿⠨⣔⣿⣿⣯⣿⢿⣾⢷⡇⣷⡈⢟⣾⣻⣿⡄⢊⠤⠙⡾⣯⣷⢿⣽⣷⣻⢾⣽⢷⣷⣎⣦⡈⠛⢿⣆⠘⡵⢂⢺⡇⢺⣿⡽⣿⣼⣿⣼⢸⡽⣽⡳⣟⡽⣞⣻⠷⣞
⣽⣻⡽⣿⣳⣟⣾⣯⢿⠞⣴⡿⢛⣠⣾⣟⣷⣻⡽⣱⣿⣿⣿⢟⣵⣿⣿⣿⣿⢣⣿⣿⣿⣿⣿⢦⣶⡶⠶⢶⠂⢲⣬⣭⠁⠤⢸⣯⡷⣯⡿⣞⣿⣦⢸⣿⡌⢷⣿⠯⠛⡀⠊⣁⠈⢛⡙⠻⢷⣯⣟⡿⣾⣻⢾⡽⣯⢷⡈⢢⠙⢷⣄⠉⢆⡷⢸⣿⡽⣯⢿⣽⣾⢈⡷⢯⣽⣫⡽⣏⣷⣻⡽
⣽⣻⡽⣿⣿⣯⣿⣾⢋⠜⣫⣴⣿⣻⡷⣟⣾⡿⢰⡿⠿⠿⠣⡾⠿⢿⣛⣛⡛⣸⣿⣭⣭⣭⡏⣐⣶⣾⢿⠏⣸⠘⣷⣻⡇⠘⡄⣿⣽⢷⣿⣻⢷⣟⠘⣿⣿⣂⢻⣞⣿⣧⡀⠠⠍⡄⠹⣿⣶⣦⣙⠻⣷⣟⣯⣿⡽⣿⣷⡄⢉⠆⡙⢦⠈⣿⢸⣯⡿⣽⣯⣿⢿⠀⣟⣟⣮⢷⣻⢽⡞⣵⣻
⣽⣻⣟⣿⣿⡾⣷⠃⣠⣾⣿⣷⡿⣟⡿⣯⡷⢡⣶⡿⠏⣴⣿⢿⡿⣟⣯⡿⠁⣿⣳⡿⣯⢿⠇⣾⢯⠟⣩⢀⣶⣦⢠⣍⡳⡈⠔⢸⣯⡿⣾⡽⣯⣿⡅⣿⣿⣿⣦⡙⢾⣿⣷⡘⣄⠨⠅⡌⢳⣿⡽⣷⣼⣻⣞⣷⣟⣷⣻⣷⡈⠰⢡⠊⡑⡌⢸⣷⣟⣯⢷⡿⣿⢀⡿⣞⡽⡾⣭⢷⣻⣳⡽
⢾⣽⣯⣿⣿⣽⢃⣾⣿⣟⣷⡿⣿⣟⣿⣻⠃⣾⣟⢃⣼⡿⣽⣯⢿⡿⡝⢠⢀⡿⣷⣟⣿⣻⠀⣟⣡⣾⠏⣼⣿⣿⡄⢟⣿⣧⠘⡀⢿⣽⣳⣿⡽⣷⣇⢻⣿⣿⣿⣶⡈⢳⣟⣧⡸⣷⣌⢐⡂⠙⣿⣽⣾⢯⡿⣾⣽⣞⣯⣿⣳⠈⢆⠱⣂⠄⡈⢾⣟⡾⣿⣽⣿⢨⢷⣏⡿⣽⣹⢯⢷⣛⣾
⣻⢾⡷⣿⣿⣯⣿⣿⡿⣾⢿⣽⣟⡿⣾⡽⢰⣿⢃⡾⣽⣻⣽⡾⣟⡟⢀⠆⢸⡿⣽⡾⣯⢿⠐⣿⣯⣿⢠⣿⣿⣿⣿⡈⢾⣿⣆⠡⠌⢷⣟⣾⡽⣿⢾⠸⣿⣿⣿⣿⣿⣆⠙⣿⣧⠹⣿⣷⣄⠃⠌⠳⣿⣻⣽⣟⣾⣽⣻⣞⡿⣷⡈⠒⣌⠒⡥⢈⢾⣻⡽⣷⣻⢨⢷⢾⣽⣳⢯⣟⣯⣟⢾
⣽⣻⣟⣿⣽⡿⣯⣷⢿⣻⡿⣾⣽⣿⣳⡇⣼⢃⣾⢿⡽⣯⣷⢿⡝⠠⢌⠎⢸⣟⡷⣿⣟⡯⢘⡿⣾⡇⣼⣿⣿⣿⣿⣷⡐⣯⢿⡄⢊⠘⣿⢾⣽⣻⡿⡇⢿⣿⣿⣿⣿⣿⣷⣄⠻⣧⠹⣿⣿⣷⣌⠡⠈⢿⣳⣯⢿⣞⡷⣯⢿⣽⣷⡈⠄⡓⢌⠦⡀⢻⣽⣟⣯⠸⣯⣞⢷⡯⣟⡾⣵⣞⡿
⢾⣽⣞⣿⣟⣿⣽⣯⢿⣻⣽⣟⣯⣷⢿⡇⠇⣼⣯⣟⡿⣽⣯⡟⠠⡘⠆⠎⢸⣿⡽⣟⣾⡇⠐⣿⢿⠁⣿⣿⣿⣿⣿⣿⣷⡩⢿⣧⢀⠊⢽⣯⣟⡷⣿⣳⢸⣿⣿⣿⣿⣿⣿⣿⣷⡌⠧⠙⠿⠿⢿⣓⣤⡀⠙⠯⢿⣻⢿⡽⣟⣾⣽⣧⠀⡈⠒⢢⠱⡀⢻⣾⡗⢸⣳⣞⣯⢿⣹⣽⣳⣻⢾
⣻⢾⣯⣿⣾⣟⡷⣿⣯⢿⣽⢾⣻⣯⡿⡇⢰⣿⣳⢯⣿⣳⣯⠁⠦⡙⢌⠣⢸⣯⣟⣿⣳⠂⡄⣿⣻⢰⣿⣿⣿⣿⣿⣿⣿⣧⡙⣿⡌⣦⠃⢻⣞⣿⡽⣿⡄⣿⣿⣿⣯⣭⣭⣷⢶⠶⠦⠐⠘⠛⠉⠉⠀⠀⣀⠀⠰⢯⣿⣻⣟⣾⡽⣿⣆⠀⠳⠄⠣⠑⡄⢻⡇⢸⢷⢾⣭⣟⣳⢯⣷⢻⣾
⣽⣻⣞⣿⣷⣻⡿⣷⣯⢿⣯⣿⢿⣷⣻⡇⣼⡷⣟⣿⣳⣿⠃⠌⣒⠩⡌⡱⢸⣟⣾⣽⣻⢀⠆⢸⡿⠸⠿⠯⠭⣭⣭⣭⣭⣭⣥⠈⡇⢹⣧⠁⢹⡾⣿⢿⣇⢹⣿⣿⣿⣗⡀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠘⣿⡆⣷⡌⢿⣳⣿⣳⡿⣯⢿⡄⣿⣿⣦⡈⡐⠀⠃⢼⣯⣟⡾⣭⣟⣯⣞⣿⢺
⢾⣽⢯⣿⡾⣟⣿⣳⣯⡿⣷⣻⣿⢯⣿⢃⣿⣽⢯⡿⣽⡞⢀⠨⠰⡑⢢⡑⠈⣿⢾⣽⣻⠤⢘⠘⣿⢠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠄⣿⣷⡀⠹⣿⣻⣿⠌⣿⣿⣿⣿⣿⣿⠀⠀⠄⠂⠐⠈⡐⠀⠡⠀⢻⡅⣿⠠⡠⠙⣾⢯⣿⡽⣯⣇⠸⢍⣹⡇⣿⣦⠀⢻⢶⣯⢟⣳⡽⣞⣧⣟⢯
⣻⢾⣯⣿⣟⣿⢷⣯⡷⣿⢯⣷⣿⣻⣽⠰⣿⣞⣿⣻⢿⢁⣾⠀⢣⠱⣁⠚⡄⡿⣟⣾⣽⡂⢸⡇⢃⢸⣧⠘⣿⡆⠀⡀⡀⢀⠀⠄⠰⣄⠸⣿⣿⣄⠹⣿⡽⡇⢻⣿⣿⣿⣿⣿⡀⢈⠀⡇⠠⢁⠠⠈⡐⠠⢸⣸⡇⠰⡡⢃⠈⢿⣳⣿⢯⣿⠆⢿⣿⡇⣷⣻⡇⢈⡿⣞⣯⢿⣽⣻⢾⣭⢿
⢿⣿⡾⣿⣿⣿⣿⣿⢿⣿⡿⣿⣿⣿⡿⢸⣿⣿⣿⣿⡏⣸⣿⠀⠏⠤⢋⢧⡀⢸⣿⢿⣿⡇⢸⣿⠀⠀⣿⣧⢸⣧⠀⠀⡃⢀⠘⠀⠀⣿⣦⠸⣿⣿⣦⠸⣿⣷⠸⣿⣿⣿⣿⣿⣧⠀⠠⣿⠀⠀⠄⢀⡇⠀⣿⣿⠃⣃⢳⠋⠘⡀⠻⣿⡿⣿⣷⢸⣿⢃⣿⣿⡇⢸⡿⣿⡿⡿⣿⣟⡿⣿⢿
⣻⢾⣻⣿⢯⣿⢾⣯⣟⡷⣟⣿⣻⣞⡿⢸⣟⣾⣽⠞⣰⡿⣽⡆⢌⠣⣉⠦⡘⡈⣾⡿⣽⡇⢸⡿⣆⠐⠘⢿⣆⢿⡄⠀⢣⠀⠂⢸⡀⢹⣿⣧⣽⣿⣿⣦⠑⣿⡇⢿⣿⣿⣿⣿⣹⡿⣿⣽⣷⣬⣴⣿⠷⣴⣿⣿⠠⡘⠤⢃⠃⡔⡀⡙⢿⣻⢿⡄⠏⣾⢷⡿⣇⢸⣽⣳⢿⣽⣳⢯⡿⣽⢾
⣻⣟⡷⣿⣿⣻⡿⣾⢯⣿⣻⣟⣿⡽⣟⢸⣯⢷⡏⢰⣿⣻⢯⣇⢈⢒⢡⢒⡡⣁⢱⣿⢷⣯⢸⣿⡽⠀⢃⠈⢿⣎⣿⣴⣿⣧⣶⣿⡇⢾⣿⣿⣿⣿⣿⣿⣷⡘⢧⠘⣿⣿⣿⣿⣷⡿⣄⠈⠛⠻⠟⢋⣰⢟⣽⡇⠰⢡⠃⣸⠰⡘⢠⡇⣌⠻⣯⣷⢸⡿⣯⣿⢧⢸⣳⢯⣟⡾⣽⢯⣟⡷⣻
⣟⣾⣟⣿⣷⢯⣿⣟⡿⣞⣷⣯⣿⡽⣯⢸⣻⣿⢁⣿⣯⣟⣿⣻⡀⠎⢢⠅⣒⢡⠀⣿⣟⣾⡼⣷⣟⠠⣉⢆⠈⢿⣯⡻⣎⠉⠛⠛⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣦⡁⢹⣿⣿⣿⣿⣿⣿⣭⣶⣶⣮⣵⣾⣿⡿⢁⠡⣃⢂⡿⢠⠁⣾⠇⢛⣥⠙⣿⠀⣿⣻⣽⣻⢸⡽⣻⢾⡽⣯⣟⡾⣽⣻
⡿⢾⡽⣿⣾⢿⣻⡾⣟⣿⣽⣾⢯⣟⣿⠰⣿⠇⣼⣟⣾⢿⣳⡿⣧⠘⠤⢩⡐⢊⡔⠈⣿⣞⡿⣷⣻⢀⠲⡈⠖⡀⢻⣿⣯⣥⣤⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⢠⢃⡄⣸⡗⢠⢰⡟⠠⢸⢻⡀⠌⠂⢿⡽⣷⣿⢸⡽⢯⡿⣽⣳⢯⣟⡷⣯
⣻⢿⣻⣿⡽⣿⣻⢿⣽⡾⣟⣾⢿⣻⣽⡆⡿⢰⣯⣿⢾⣟⡿⣽⡿⣆⠨⢡⠌⠣⣌⠁⠘⣯⣟⣿⣽⠀⣒⠩⠜⡰⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⢆⣊⢀⣿⡇⢀⣾⠃⠰⠈⣿⡇⢈⢧⣸⣟⣷⢿⢨⣟⣯⣟⡷⣯⣟⡾⣽⣳
⣻⣟⡷⣿⣟⣿⣯⡿⣞⣿⢯⣿⣿⣯⢿⡇⠁⣼⣿⣞⣿⣯⣿⢯⣟⣿⡄⠃⡜⢡⠢⡁⢣⡘⡿⣞⣿⠀⠤⠃⠘⣄⠃⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⣟⣛⣭⣭⡙⣿⣿⣿⣿⣿⣿⡿⠈⢆⠄⣼⡿⡇⣸⡟⠠⠘⡀⣿⣳⢈⢸⣟⣾⢯⣿⠐⣯⢾⣽⣳⣟⡾⣽⣳⢯
⣳⢿⡽⣿⣟⣯⣿⢿⣽⣾⢿⣳⡿⣯⡿⣿⠀⣿⣿⣞⣿⣳⣿⢯⣟⣾⢿⡄⠘⠤⠓⡄⢹⣷⡘⣽⡿⡇⠈⡇⠘⡄⢣⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⡄⢼⣿⣿⣿⣿⣿⢇⣿⣿⣿⡿⠟⠋⠁⠜⡨⢰⣿⢻⢁⣿⠃⠰⡀⠄⣿⢿⡄⢺⣯⣟⣿⣽⠀⣿⣻⣞⡷⣯⣟⡷⣯⢿
⣽⣻⣿⣷⡿⠿⠺⠿⢯⣿⣻⢿⣽⣿⡽⣿⣞⣿⣳⡟⣋⣍⠻⣯⣟⣾⢯⣿⡄⠡⢋⠔⢸⣷⢷⡈⢿⣧⠘⡰⠀⡅⢣⠡⠘⢤⠈⣉⠙⡛⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣶⣭⣭⣯⠭⠵⣚⣛⣭⣶⣾⡇⠈⢠⠙⢀⡟⢆⣿⡿⡏⢀⠳⣀⠀⢻⣯⣷⠩⣷⣻⣾⣽⠀⣷⣻⢾⣽⣳⢯⡿⣽⣻
⣻⣟⣷⡋⣴⣿⣿⣿⣶⣶⣭⣛⠾⢯⣟⣷⣿⢷⣻⢰⣿⣿⣧⢹⢾⣯⢿⣞⣿⣆⠈⢎⠘⣯⣟⣿⠈⢻⡄⢢⠁⡘⢢⡑⠈⠆⡥⠀⡓⣌⠒⢬⠀⢄⠢⡐⠤⠩⠉⡉⢍⠀⡀⠀⣠⣿⣿⣿⣿⣿⡿⢁⠀⢆⡉⡼⡉⣼⣿⡍⠠⠌⣒⠡⡀⢸⡷⣟⡆⣿⣳⢿⣾⠄⡿⣽⣻⢾⡽⣯⣟⣷⣻
⣳⣟⣿⣧⠻⢿⣿⣿⣿⣿⣿⣿⣿⣶⣍⡻⢽⣿⣿⡘⣿⣿⣿⡌⢿⣯⣿⢾⣳⡿⣧⡈⠀⣿⣟⣾⠨⢀⠁⠠⢃⠘⠰⢌⠀⢑⠰⢂⠱⣀⠫⠤⣉⠀⠣⠘⣈⠠⡑⠌⣠⣴⣶⣿⣿⣿⣿⣿⣿⠋⡀⠆⠰⡈⢰⣣⢱⣿⣳⢃⠞⡢⠄⣁⣄⠘⠿⣟⣯⡿⣽⣻⣾⠇⣟⣷⣻⣯⣟⣷⣻⢾⣽
⣿⣯⣿⡿⣿⡶⠮⠭⠝⠛⠻⠿⢿⣿⣿⣿⣶⣶⣶⣥⣘⠿⣿⣿⣎⠳⣯⢿⣯⣟⣿⣻⣄⢹⠾⢛⡀⠈⢆⡀⠥⡀⠍⢢⠀⣦⡁⠣⠄⠠⢃⡁⡔⢢⢣⡝⡰⠂⣈⣐⣛⣛⠿⣿⣿⣿⣿⠟⠁⡠⢔⠃⡰⢁⡏⢤⣿⡻⠅⢐⣨⣶⠟⣫⢐⠮⣄⡈⠳⣿⣻⣽⣾⡇⣟⣾⣽⢾⡽⣾⣽⣻⢾
⣿⠷⣋⣭⣴⣶⣾⣿⣿⣿⣶⣶⡦⣠⣶⣾⣶⣝⠻⣿⣿⣿⣾⣿⣿⣷⡍⣿⢾⣽⣾⠿⢉⣴⣾⣿⡇⠀⢎⡐⢢⡁⠘⢤⠁⣬⡑⠂⣴⠠⢸⢰⡉⢧⢣⠜⡑⣼⣿⣿⣯⣟⣻⣶⣭⡛⢡⡐⢮⣑⠃⠤⢁⡾⠌⣾⣟⠇⣴⠿⡫⢄⡳⠬⢉⣂⣥⣥⡀⢹⢷⣿⣾⡇⢻⣞⣯⡿⣽⢷⣯⣟⣿
⣵⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⠿⢿⣿⣧⣹⣿⣿⣿⣿⣿⣿⣧⢹⣿⣳⠏⣴⣿⣿⣿⣿⣷⢀⠦⣉⠒⣌⠀⠎⡐⢸⠰⠃⣿⠀⣿⢠⡙⢦⢍⠞⢰⣿⣿⣿⣿⣿⣿⣿⠟⢄⡲⢍⠶⡡⢀⢃⣾⠱⣸⣿⡛⠘⢥⡚⠔⣩⣴⣿⣿⣿⣿⣿⣿⣦⢻⣞⡿⡇⢸⣯⡷⣿⢯⣟⡾⣽⢾
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢨⣿⣿⣿⣿⣯⡄⢝⢿⣿⣿⣿⣿⡿⡈⠛⡃⣘⠻⢿⣿⣿⣿⣿⡀⠲⢄⢋⠤⠃⡈⠱⡈⠸⠁⣿⠀⣿⢠⠹⣌⡚⢄⣿⣿⣿⣿⣿⣿⡿⡁⠞⣬⠱⣎⢣⠅⠀⣾⢃⢣⣿⠓⣠⠙⢆⣵⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠻⣿⣧⢸⣳⡿⣯⢿⣞⡿⣽⣻
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⣿⠟⣭⣭⣭⣭⣛⢊⣃⣽⣿⣿⣿⣷⣷⡈⠱⣊⠵⣂⠙⣿⣿⣿⣇⠱⠨⢌⡒⡁⢡⠑⡀⢸⠁⣿⠐⢸⡀⢯⡰⠩⣸⣿⣿⣿⣿⣿⠟⠤⣍⢫⡔⣫⠔⠃⠀⢰⢿⡶⣿⡽⠠⢆⣵⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡌⣻⣽⢸⣳⢿⣻⣟⣾⡽⣷⣻
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡌⢼⣿⣿⣿⣿⡿⣸⣿⣿⣿⣿⣿⣿⣿⣷⡀⠈⡳⢌⣃⠸⣿⣿⣿⡀⡙⠤⢊⠅⢈⣆⠑⡀⠃⣿⡘⢸⡆⡣⢕⢣⣿⣿⣿⣿⣿⠏⡨⢞⡰⡃⢊⡵⠊⠀⠂⣼⢯⣿⡽⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢘⣿⠄⣿⣻⡷⣿⣞⣿⣳⢿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠸⣿⣿⣏⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢠⠑⡮⢰⢰⠘⢿⣿⣇⠨⠥⣉⠆⢸⣿⣆⠀⠀⣿⡇⠎⡇⢱⠋⣼⣿⣿⣿⣿⢃⢎⠵⠃⣡⠖⡩⢂⣤⡾⢠⣿⢿⣽⢃⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢹⡆⣻⣽⣻⣷⣯⡷⣟⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣝⡻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⠯⣔⢣⢸⢘⣠⢩⣝⠀⠣⡔⠊⢸⣿⣿⡆⠀⢸⡇⡃⢿⢠⠃⣿⣿⣿⣿⠃⡎⢎⣴⠟⡁⣢⣴⠟⣫⠀⢹⡾⣿⢃⣾⣿⣿⣿⣿⣿⣿⣿⣿⣯⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⠘⡇⢼⣻⡷⣯⣷⢿⣻⣾
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢡⣶⣶⡆⡐⣀⠙⢿⣿⣿⣿⣿⠇⣊⠶⣌⠃⡇⡜⢰⠋⣿⣷⡐⢌⢣⢸⣿⣿⣿⡀⠈⣿⠘⠸⡄⢸⣿⣿⣿⠃⢊⡴⠋⢁⣠⡾⢟⢅⡚⠔⢠⣿⢿⠋⣼⡿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣽⣻⠿⣿⣿⣿⣿⣿⡗⣶⣌⢻⣿⣽⢿⣻⢷⣻
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢃⣾⣟⡿⢠⠁⡄⢣⠈⢻⣿⣿⠏⣔⢊⠶⡌⡘⡰⡉⣼⠠⢹⣿⣧⠈⢆⠌⣿⣿⣿⠁⠄⢸⡎⠅⢇⢸⣿⡿⢁⡔⠋⢐⣴⡿⢋⡔⡣⢊⣴⡏⢰⣯⠇⢰⣟⢿⣿⣿⣾⣽⣟⣿⢿⣿⣿⣿⣿⣿⣿⣷⣷⣻⢽⣟⣿⣷⣻⣿⡆⣿⢾⣟⣿⢯⣿
⣝⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢣⣾⣿⣿⠁⡆⢈⠔⡡⢊⠄⠻⣋⠲⠬⣍⠖⡴⢡⠓⣰⠇⡆⣼⣿⣿⣆⠘⡀⣿⣿⡇⣷⠘⡄⢳⠘⠸⢸⣿⠃⡊⢔⣴⠟⡩⣔⠣⣈⣴⣿⣿⡇⢸⡯⠀⣿⣿⣎⢷⣯⣟⡿⣿⣿⣿⣾⣯⣟⣿⢿⣿⣿⣿⣿⣷⣯⣟⡿⢏⣿⣇⢻⡿⣯⣿⣟⣾
⣿⣷⣮⡝⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣝⢳⡏⡘⡄⢈⠆⡱⠈⣠⢚⠴⣋⠳⣠⢎⠴⡉⣰⢏⠼⢀⣿⣿⣿⣿⡆⠡⢸⣿⢸⣿⡧⢘⠘⡆⠇⣿⠇⢄⣵⠟⡡⢎⢑⣠⣾⣿⣿⣿⣿⡆⢹⠁⣼⣿⣿⣿⣧⡻⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣷⣿⣽⡿⣿⣿⣿⣿⣿⣿⣿⡘⣿⣻⣷⣿⣾
⣿⣿⢋⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡅⠄⡳⢌⠤⣰⢉⢦⡙⠦⣡⠞⣡⢃⢊⡼⢣⠎⠎⣼⣿⣿⣿⣿⣷⢠⠈⡇⣿⣿⣿⡆⠣⢱⡀⢏⣴⠟⣡⠚⣁⣴⡿⢿⣯⣡⣿⣿⣿⣿⠀⣰⣯⣽⣛⣿⣿⠷⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣽⣻⢿⣿⣿⣷⡜⢷⣿⣳⣿
⣿⢧⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⣅⣋⠚⠤⣋⣢⣵⠞⣅⠳⢈⣴⠟⢑⣣⢊⣾⣿⣿⣿⣿⣿⣿⢸⢇⡠⣿⣿⣿⣿⡄⢃⠃⢘⢅⠓⠀⣚⣭⣵⣾⣿⣿⣿⣿⠿⣛⣭⣾⣿⣿⣿⣿⣿⣿⣿⣿⣮⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣎⢻⣟⣿
⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢰⣶⣶⣶⡍⠍⠆⣓⣤⡾⠟⢡⡙⠎⣠⣿⣿⣿⣿⣿⣿⣿⣿⡞⣾⣷⣌⠻⢿⣿⣿⠄⠴⢉⡤⣾⠿⠿⢿⣛⣛⣫⣭⣵⣶⣿⣿⣿⣿⣿⡙⣿⣿⣿⣿⣿⣿⣿⣷⡙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣸⣿`,
}, },
{ {
author: "https://emojicombos.com/anime-ascii-art", author: "https://emojicombos.com/anime-ascii-art",
+7
View File
@@ -4,12 +4,14 @@
* @author Naomi Carrigan * @author Naomi Carrigan
*/ */
import { DiscordAnalytics } from "@nhcarrigan/discord-analytics";
import { import {
Client, Client,
Events, Events,
GatewayIntentBits, GatewayIntentBits,
} from "discord.js"; } from "discord.js";
import { chatInputInteractionCreate } from "./events/interactionCreate.js"; import { chatInputInteractionCreate } from "./events/interactionCreate.js";
import { instantiateServer } from "./server/serve.js";
import { logger } from "./utils/logger.js"; import { logger } from "./utils/logger.js";
const chibika = new Client({ const chibika = new Client({
@@ -18,14 +20,18 @@ const chibika = new Client({
], ],
}); });
const analytics = new DiscordAnalytics(chibika, logger);
chibika.once(Events.ClientReady, () => { chibika.once(Events.ClientReady, () => {
void logger.log( void logger.log(
"debug", "debug",
`Logged in as ${chibika.user?.username ?? "unknown"}`, `Logged in as ${chibika.user?.username ?? "unknown"}`,
); );
analytics.startCron();
}); });
chibika.on(Events.InteractionCreate, (interaction) => { chibika.on(Events.InteractionCreate, (interaction) => {
void analytics.logGatewayEvent(Events.InteractionCreate, { ...interaction });
if (interaction.isChatInputCommand()) { if (interaction.isChatInputCommand()) {
if (!interaction.inCachedGuild()) { if (!interaction.inCachedGuild()) {
void interaction.reply({ void interaction.reply({
@@ -38,3 +44,4 @@ chibika.on(Events.InteractionCreate, (interaction) => {
}); });
await chibika.login(process.env.DISCORD_TOKEN); await chibika.login(process.env.DISCORD_TOKEN);
instantiateServer();
+20
View File
@@ -35,3 +35,23 @@ describe("assets", () => {
expect(uniqueEmoji.size, "emoji has duplicate art").toBe(emoji.length); expect(uniqueEmoji.size, "emoji has duplicate art").toBe(emoji.length);
}); });
}); });
describe("length", () => {
it.each(anime)("anime art should have correct length", (art) => {
expect.assertions(2);
expect(art.text.length, `${anime.indexOf(art)} has no content!`).toBeGreaterThan(0);
expect(art.text.length, `${anime.indexOf(art)} has too much content!`).toBeLessThanOrEqual(3500);
});
it.each(cats)("cats art should have correct length", (art) => {
expect.assertions(2);
expect(art.text.length, `${cats.indexOf(art)} has no content!`).toBeGreaterThan(0);
expect(art.text.length, `${cats.indexOf(art)} has too much content!`).toBeLessThanOrEqual(3500);
});
it.each(emoji)("emoji art should have correct length", (art) => {
expect.assertions(2);
expect(art.text.length, `${emoji.indexOf(art)} has no content!`).toBeGreaterThan(0);
expect(art.text.length, `${emoji.indexOf(art)} has too much content!`).toBeLessThanOrEqual(3500);
});
});