diff --git a/.dockerignore b/.dockerignore index daf6041ae..e4995fe58 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,6 +4,7 @@ npm-debug.log readme* Start.bat /dist -/backups/ +/backups cloudflared.exe access.log +/data diff --git a/.eslintrc.js b/.eslintrc.js index 981379f24..0f4a7327f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -42,11 +42,21 @@ module.exports = { showdownKatex: 'readonly', SVGInject: 'readonly', toastr: 'readonly', + Readability: 'readonly', + isProbablyReaderable: 'readonly', }, }, ], // There are various vendored libraries that shouldn't be linted - ignorePatterns: ['public/lib/**/*', '*.min.js', 'src/ai_horde/**/*'], + ignorePatterns: [ + 'public/lib/**/*', + '*.min.js', + 'src/ai_horde/**/*', + 'plugins/**/*', + 'data/**/*', + 'backups/**/*', + 'node_modules/**/*', + ], rules: { 'no-unused-vars': ['error', { args: 'none' }], 'no-control-regex': 'off', diff --git a/.gitignore b/.gitignore index 64b33ddb2..d6a5061bb 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ public/stats.json /docker/config /docker/user /docker/extensions +/docker/data .DS_Store public/settings.json /thumbnails diff --git a/Dockerfile b/Dockerfile index efae20b0e..64a92173a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:19.1.0-alpine3.16 +FROM node:lts-alpine3.18 # Arguments ARG APP_HOME=/home/node/app @@ -26,19 +26,9 @@ COPY . ./ # Copy default chats, characters and user avatars to .default folder RUN \ - IFS="," RESOURCES="assets,backgrounds,user,context,instruct,QuickReplies,movingUI,themes,characters,chats,groups,group chats,User Avatars,worlds,OpenAI Settings,NovelAI Settings,KoboldAI Settings,TextGen Settings" && \ - \ - echo "*** Store default $RESOURCES in .default ***" && \ - for R in $RESOURCES; do mv "public/$R" "public/$R.default"; done || true && \ - \ - echo "*** Create symbolic links to config directory ***" && \ - for R in $RESOURCES; do ln -s "../config/$R" "public/$R"; done || true && \ - \ - rm -f "config.yaml" "public/settings.json" || true && \ + rm -f "config.yaml" || true && \ ln -s "./config/config.yaml" "config.yaml" || true && \ - ln -s "../config/settings.json" "public/settings.json" || true && \ - mkdir "config" || true && \ - mkdir -p "public/user" || true + mkdir "config" || true # Cleanup unnecessary files RUN \ diff --git a/public/KoboldAI Settings/.gitkeep b/data/.gitkeep similarity index 100% rename from public/KoboldAI Settings/.gitkeep rename to data/.gitkeep diff --git a/default/config.yaml b/default/config.yaml index dedb5ac5f..8966447d0 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -1,8 +1,12 @@ -# -- NETWORK CONFIGURATION -- +# -- DATA CONFIGURATION -- +# Root directory for user data storage +dataRoot: ./data +# -- SERVER CONFIGURATION -- # Listen for incoming connections listen: false # Server port port: 8000 +# -- SECURITY CONFIGURATION -- # Toggle whitelist mode whitelistMode: true # Whitelist of allowed IP addresses @@ -16,7 +20,15 @@ basicAuthUser: password: "password" # Enables CORS proxy middleware enableCorsProxy: false -# Disable security checks - NOT RECOMMENDED +# Enable multi-user mode +enableUserAccounts: false +# Enable discreet login mode: hides user list on the login screen +enableDiscreetLogin: false +# Used to sign session cookies. Will be auto-generated if not set +cookieSecret: '' +# Disable CSRF protection - NOT RECOMMENDED +disableCsrfProtection: false +# Disable startup security checks - NOT RECOMMENDED securityOverride: false # -- ADVANCED CONFIGURATION -- # Open the browser automatically diff --git a/public/backgrounds/__transparent.png b/default/content/backgrounds/__transparent.png similarity index 100% rename from public/backgrounds/__transparent.png rename to default/content/backgrounds/__transparent.png diff --git a/public/backgrounds/_black.jpg b/default/content/backgrounds/_black.jpg similarity index 100% rename from public/backgrounds/_black.jpg rename to default/content/backgrounds/_black.jpg diff --git a/public/backgrounds/_white.jpg b/default/content/backgrounds/_white.jpg similarity index 100% rename from public/backgrounds/_white.jpg rename to default/content/backgrounds/_white.jpg diff --git a/public/backgrounds/bedroom clean.jpg b/default/content/backgrounds/bedroom clean.jpg similarity index 100% rename from public/backgrounds/bedroom clean.jpg rename to default/content/backgrounds/bedroom clean.jpg diff --git a/public/backgrounds/bedroom cyberpunk.jpg b/default/content/backgrounds/bedroom cyberpunk.jpg similarity index 100% rename from public/backgrounds/bedroom cyberpunk.jpg rename to default/content/backgrounds/bedroom cyberpunk.jpg diff --git a/public/backgrounds/bedroom red.jpg b/default/content/backgrounds/bedroom red.jpg similarity index 100% rename from public/backgrounds/bedroom red.jpg rename to default/content/backgrounds/bedroom red.jpg diff --git a/public/backgrounds/bedroom tatami.jpg b/default/content/backgrounds/bedroom tatami.jpg similarity index 100% rename from public/backgrounds/bedroom tatami.jpg rename to default/content/backgrounds/bedroom tatami.jpg diff --git a/public/backgrounds/cityscape medieval market.jpg b/default/content/backgrounds/cityscape medieval market.jpg similarity index 100% rename from public/backgrounds/cityscape medieval market.jpg rename to default/content/backgrounds/cityscape medieval market.jpg diff --git a/public/backgrounds/cityscape medieval night.jpg b/default/content/backgrounds/cityscape medieval night.jpg similarity index 100% rename from public/backgrounds/cityscape medieval night.jpg rename to default/content/backgrounds/cityscape medieval night.jpg diff --git a/public/backgrounds/cityscape postapoc.jpg b/default/content/backgrounds/cityscape postapoc.jpg similarity index 100% rename from public/backgrounds/cityscape postapoc.jpg rename to default/content/backgrounds/cityscape postapoc.jpg diff --git a/public/backgrounds/forest treehouse fireworks air baloons (by kallmeflocc).jpg b/default/content/backgrounds/forest treehouse fireworks air baloons (by kallmeflocc).jpg similarity index 100% rename from public/backgrounds/forest treehouse fireworks air baloons (by kallmeflocc).jpg rename to default/content/backgrounds/forest treehouse fireworks air baloons (by kallmeflocc).jpg diff --git a/public/backgrounds/japan classroom side.jpg b/default/content/backgrounds/japan classroom side.jpg similarity index 100% rename from public/backgrounds/japan classroom side.jpg rename to default/content/backgrounds/japan classroom side.jpg diff --git a/public/backgrounds/japan classroom.jpg b/default/content/backgrounds/japan classroom.jpg similarity index 100% rename from public/backgrounds/japan classroom.jpg rename to default/content/backgrounds/japan classroom.jpg diff --git a/public/backgrounds/japan path cherry blossom.jpg b/default/content/backgrounds/japan path cherry blossom.jpg similarity index 100% rename from public/backgrounds/japan path cherry blossom.jpg rename to default/content/backgrounds/japan path cherry blossom.jpg diff --git a/public/backgrounds/japan university.jpg b/default/content/backgrounds/japan university.jpg similarity index 100% rename from public/backgrounds/japan university.jpg rename to default/content/backgrounds/japan university.jpg diff --git a/public/backgrounds/landscape autumn great tree.jpg b/default/content/backgrounds/landscape autumn great tree.jpg similarity index 100% rename from public/backgrounds/landscape autumn great tree.jpg rename to default/content/backgrounds/landscape autumn great tree.jpg diff --git a/public/backgrounds/landscape beach day.png b/default/content/backgrounds/landscape beach day.png similarity index 100% rename from public/backgrounds/landscape beach day.png rename to default/content/backgrounds/landscape beach day.png diff --git a/public/backgrounds/landscape beach night.jpg b/default/content/backgrounds/landscape beach night.jpg similarity index 100% rename from public/backgrounds/landscape beach night.jpg rename to default/content/backgrounds/landscape beach night.jpg diff --git a/public/backgrounds/landscape mountain lake.jpg b/default/content/backgrounds/landscape mountain lake.jpg similarity index 100% rename from public/backgrounds/landscape mountain lake.jpg rename to default/content/backgrounds/landscape mountain lake.jpg diff --git a/public/backgrounds/landscape postapoc.jpg b/default/content/backgrounds/landscape postapoc.jpg similarity index 100% rename from public/backgrounds/landscape postapoc.jpg rename to default/content/backgrounds/landscape postapoc.jpg diff --git a/public/backgrounds/landscape winter lake house.jpg b/default/content/backgrounds/landscape winter lake house.jpg similarity index 100% rename from public/backgrounds/landscape winter lake house.jpg rename to default/content/backgrounds/landscape winter lake house.jpg diff --git a/public/backgrounds/royal.jpg b/default/content/backgrounds/royal.jpg similarity index 100% rename from public/backgrounds/royal.jpg rename to default/content/backgrounds/royal.jpg diff --git a/public/backgrounds/tavern day.jpg b/default/content/backgrounds/tavern day.jpg similarity index 100% rename from public/backgrounds/tavern day.jpg rename to default/content/backgrounds/tavern day.jpg diff --git a/default/content/index.json b/default/content/index.json index d4ef03cb6..06c927d4d 100644 --- a/default/content/index.json +++ b/default/content/index.json @@ -1,4 +1,108 @@ [ + { + "filename": "settings.json", + "type": "settings" + }, + { + "filename": "themes/Dark Lite.json", + "type": "theme" + }, + { + "filename": "themes/Cappuccino.json", + "type": "theme" + }, + { + "filename": "backgrounds/__transparent.png", + "type": "background" + }, + { + "filename": "backgrounds/_black.jpg", + "type": "background" + }, + { + "filename": "backgrounds/_white.jpg", + "type": "background" + }, + { + "filename": "backgrounds/bedroom clean.jpg", + "type": "background" + }, + { + "filename": "backgrounds/bedroom cyberpunk.jpg", + "type": "background" + }, + { + "filename": "backgrounds/bedroom red.jpg", + "type": "background" + }, + { + "filename": "backgrounds/bedroom tatami.jpg", + "type": "background" + }, + { + "filename": "backgrounds/cityscape medieval market.jpg", + "type": "background" + }, + { + "filename": "backgrounds/cityscape medieval night.jpg", + "type": "background" + }, + { + "filename": "backgrounds/cityscape postapoc.jpg", + "type": "background" + }, + { + "filename": "backgrounds/forest treehouse fireworks air baloons (by kallmeflocc).jpg", + "type": "background" + }, + { + "filename": "backgrounds/japan classroom side.jpg", + "type": "background" + }, + { + "filename": "backgrounds/japan classroom.jpg", + "type": "background" + }, + { + "filename": "backgrounds/japan path cherry blossom.jpg", + "type": "background" + }, + { + "filename": "backgrounds/japan university.jpg", + "type": "background" + }, + { + "filename": "backgrounds/landscape autumn great tree.jpg", + "type": "background" + }, + { + "filename": "backgrounds/landscape beach day.png", + "type": "background" + }, + { + "filename": "backgrounds/landscape beach night.jpg", + "type": "background" + }, + { + "filename": "backgrounds/landscape mountain lake.jpg", + "type": "background" + }, + { + "filename": "backgrounds/landscape postapoc.jpg", + "type": "background" + }, + { + "filename": "backgrounds/landscape winter lake house.jpg", + "type": "background" + }, + { + "filename": "backgrounds/royal.jpg", + "type": "background" + }, + { + "filename": "backgrounds/tavern day.jpg", + "type": "background" + }, { "filename": "default_Seraphina.png", "type": "character" @@ -211,7 +315,6 @@ "filename": "presets/novel/Writers-Daemon-Kayra.json", "type": "novel_preset" }, - { "filename": "presets/textgen/Asterism.json", "type": "textgen_preset" @@ -527,5 +630,17 @@ { "filename": "presets/instruct/Llama 3 Instruct.json", "type": "instruct" + }, + { + "filename": "presets/moving-ui/Default.json", + "type": "moving_ui" + }, + { + "filename": "presets/moving-ui/Black Magic Time.json", + "type": "moving_ui" + }, + { + "filename": "presets/quick-replies/Default.json", + "type": "quick_replies" } ] diff --git a/public/movingUI/Black Magic Time.json b/default/content/presets/moving-ui/Black Magic Time.json similarity index 100% rename from public/movingUI/Black Magic Time.json rename to default/content/presets/moving-ui/Black Magic Time.json diff --git a/public/movingUI/Default.json b/default/content/presets/moving-ui/Default.json similarity index 100% rename from public/movingUI/Default.json rename to default/content/presets/moving-ui/Default.json diff --git a/public/QuickReplies/Default.json b/default/content/presets/quick-replies/Default.json similarity index 100% rename from public/QuickReplies/Default.json rename to default/content/presets/quick-replies/Default.json diff --git a/default/settings.json b/default/content/settings.json similarity index 98% rename from default/settings.json rename to default/content/settings.json index dbd731c45..aef108eac 100644 --- a/default/settings.json +++ b/default/content/settings.json @@ -95,7 +95,7 @@ "user_prompt_bias": "", "show_user_prompt_bias": true, "markdown_escape_strings": "", - "fast_ui_mode": false, + "fast_ui_mode": true, "avatar_style": 0, "chat_display": 0, "chat_width": 50, @@ -115,16 +115,17 @@ "italics_text_color": "rgba(145, 145, 145, 1)", "underline_text_color": "rgba(188, 231, 207, 1)", "quote_text_color": "rgba(225, 138, 36, 1)", + "chat_tint_color": "rgba(23, 23, 23, 1)", "blur_tint_color": "rgba(23, 23, 23, 1)", - "user_mes_blur_tint_color": "rgba(0, 0, 0, 0.9)", - "bot_mes_blur_tint_color": "rgba(0, 0, 0, 0.9)", + "user_mes_blur_tint_color": "rgba(30, 30, 30, 0.9)", + "bot_mes_blur_tint_color": "rgba(30, 30, 30, 0.9)", "shadow_color": "rgba(0, 0, 0, 1)", "waifuMode": false, "movingUI": false, "movingUIState": {}, "movingUIPreset": "Default", "noShadows": true, - "theme": "Default (Dark) 1.7.1", + "theme": "Dark Lite", "auto_swipe": false, "auto_swipe_minimum_length": 0, "auto_swipe_blacklist": [], @@ -139,7 +140,7 @@ "hotswap_enabled": true, "timer_enabled": false, "timestamps_enabled": true, - "timestamp_model_icon": false, + "timestamp_model_icon": true, "mesIDDisplay_enabled": false, "max_context_unlocked": false, "prefer_character_prompt": true, @@ -193,7 +194,8 @@ "encode_tags": false, "enableLabMode": false, "enableZenSliders": false, - "ui_mode": 1 + "ui_mode": 1, + "forbid_external_media": true }, "extension_settings": { "apiUrl": "http://localhost:5100", diff --git a/default/content/themes/Cappuccino.json b/default/content/themes/Cappuccino.json new file mode 100644 index 000000000..daf12dcd2 --- /dev/null +++ b/default/content/themes/Cappuccino.json @@ -0,0 +1,35 @@ +{ + "name": "Cappuccino", + "blur_strength": 3, + "main_text_color": "rgba(255, 255, 255, 1)", + "italics_text_color": "rgba(230, 210, 190, 1)", + "underline_text_color": "rgba(205, 180, 160, 1)", + "quote_text_color": "rgba(165, 140, 115, 1)", + "blur_tint_color": "rgba(34, 30, 32, 0.95)", + "chat_tint_color": "rgba(50, 45, 50, 0.75)", + "user_mes_blur_tint_color": "rgba(34, 30, 32, 0.75)", + "bot_mes_blur_tint_color": "rgba(34, 30, 32, 0.75)", + "shadow_color": "rgba(0, 0, 0, 0.3)", + "shadow_width": 1, + "border_color": "rgba(80, 80, 80, 0.89)", + "font_scale": 1, + "fast_ui_mode": false, + "waifuMode": false, + "avatar_style": 0, + "chat_display": 1, + "noShadows": false, + "chat_width": 50, + "timer_enabled": false, + "timestamps_enabled": true, + "timestamp_model_icon": true, + "mesIDDisplay_enabled": true, + "message_token_count_enabled": false, + "expand_message_actions": false, + "enableZenSliders": false, + "enableLabMode": false, + "hotswap_enabled": true, + "custom_css": "", + "bogus_folders": true, + "reduced_motion": false, + "compact_input_area": true +} diff --git a/default/content/themes/Dark Lite.json b/default/content/themes/Dark Lite.json new file mode 100644 index 000000000..452d7c882 --- /dev/null +++ b/default/content/themes/Dark Lite.json @@ -0,0 +1,35 @@ +{ + "name": "Dark Lite", + "blur_strength": 10, + "main_text_color": "rgba(220, 220, 210, 1)", + "italics_text_color": "rgba(145, 145, 145, 1)", + "underline_text_color": "rgba(188, 231, 207, 1)", + "quote_text_color": "rgba(225, 138, 36, 1)", + "blur_tint_color": "rgba(23, 23, 23, 1)", + "chat_tint_color": "rgba(23, 23, 23, 1)", + "user_mes_blur_tint_color": "rgba(30, 30, 30, 0.9)", + "bot_mes_blur_tint_color": "rgba(30, 30, 30, 0.9)", + "shadow_color": "rgba(0, 0, 0, 1)", + "shadow_width": 2, + "border_color": "rgba(0, 0, 0, 1)", + "font_scale": 1, + "fast_ui_mode": true, + "waifuMode": false, + "avatar_style": 0, + "chat_display": 0, + "noShadows": true, + "chat_width": 50, + "timer_enabled": false, + "timestamps_enabled": true, + "timestamp_model_icon": true, + "mesIDDisplay_enabled": false, + "message_token_count_enabled": false, + "expand_message_actions": false, + "enableZenSliders": "", + "enableLabMode": "", + "hotswap_enabled": true, + "custom_css": "", + "bogus_folders": true, + "reduced_motion": false, + "compact_input_area": true +} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index d96c21fe4..2f1f68676 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -8,7 +8,6 @@ services: ports: - "8000:8000" volumes: - - "./extensions:/home/node/app/public/scripts/extensions/third-party" - "./config:/home/node/app/config" - - "./user:/home/node/app/public/user" + - "./data:/home/node/app/data" restart: unless-stopped diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index bafbdaf62..169a6517e 100644 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -1,38 +1,9 @@ #!/bin/sh -# Initialize missing user files -IFS="," RESOURCES="assets,backgrounds,user,context,instruct,QuickReplies,movingUI,themes,characters,chats,groups,group chats,User Avatars,worlds,OpenAI Settings,NovelAI Settings,KoboldAI Settings,TextGen Settings" -for R in $RESOURCES; do - if [ ! -e "config/$R" ]; then - echo "Resource not found, copying from defaults: $R" - cp -r "public/$R.default" "config/$R" - fi -done - if [ ! -e "config/config.yaml" ]; then echo "Resource not found, copying from defaults: config.yaml" cp -r "default/config.yaml" "config/config.yaml" fi -if [ ! -e "config/settings.json" ]; then - echo "Resource not found, copying from defaults: settings.json" - cp -r "default/settings.json" "config/settings.json" -fi - -CONFIG_FILE="config.yaml" - -echo "Starting with the following config:" -cat $CONFIG_FILE - -if grep -q "listen: false" $CONFIG_FILE; then - echo -e "\033[1;31mThe listen parameter is set to false. If you can't connect to the server, edit the \"docker/config/config.yaml\" file and restart the container.\033[0m" - sleep 5 -fi - -if grep -q "whitelistMode: true" $CONFIG_FILE; then - echo -e "\033[1;31mThe whitelistMode parameter is set to true. If you can't connect to the server, edit the \"docker/config/config.yaml\" file and restart the container.\033[0m" - sleep 5 -fi - # Start the server -exec node server.js +exec node server.js --listen diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 000000000..2769df508 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,20 @@ +import { UserDirectoryList, User } from "./src/users"; + +declare global { + namespace Express { + export interface Request { + user: { + profile: User; + directories: UserDirectoryList; + }; + } + } +} + +declare module 'express-session' { + export interface SessionData { + handle: string; + touch: number; + // other properties... + } + } diff --git a/jsconfig.json b/jsconfig.json index 652e04b1c..e7691789d 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -12,6 +12,9 @@ }, "exclude": [ "node_modules", - "**/node_modules/*" + "**/node_modules/*", + "public/lib", + "backups/*", + "data/*" ] -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index dae181ed8..93c8ed8ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sillytavern", - "version": "1.11.8", + "version": "1.12.0-preview", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sillytavern", - "version": "1.11.8", + "version": "1.12.0-preview", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { @@ -14,17 +14,21 @@ "@agnai/web-tokenizers": "^0.1.3", "@dqbd/tiktoken": "^1.0.13", "@zeldafan0225/ai_horde": "^4.0.1", + "archiver": "^7.0.1", "bing-translate-api": "^2.9.1", "body-parser": "^1.20.2", "command-exists": "^1.2.9", "compression": "^1", "cookie-parser": "^1.4.6", + "cookie-session": "^2.1.0", "cors": "^2.8.5", "csrf-csrf": "^2.2.3", "express": "^4.19.2", "form-data": "^4.0.0", "google-translate-api-browser": "^3.0.1", "gpt3-tokenizer": "^1.1.5", + "he": "^1.2.0", + "helmet": "^7.1.0", "ip-matching": "^2.1.2", "ipaddr.js": "^2.0.1", "jimp": "^0.22.10", @@ -32,10 +36,12 @@ "mime-types": "^2.1.35", "multer": "^1.4.5-lts.1", "node-fetch": "^2.6.11", + "node-persist": "^4.0.1", "open": "^8.4.2", "png-chunk-text": "^1.0.0", "png-chunks-encode": "^1.0.0", "png-chunks-extract": "^1.0.0", + "rate-limiter-flexible": "^5.0.0", "response-time": "^2.3.2", "sanitize-filename": "^1.6.3", "sillytavern-transformers": "^2.14.6", @@ -52,6 +58,7 @@ "sillytavern": "server.js" }, "devDependencies": { + "@types/jquery": "^3.5.29", "eslint": "^8.55.0", "jquery": "^3.6.4" } @@ -221,6 +228,95 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@jimp/bmp": { "version": "0.22.10", "license": "MIT", @@ -640,6 +736,15 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "license": "BSD-3-Clause" @@ -726,6 +831,15 @@ "version": "4.0.2", "license": "MIT" }, + "node_modules/@types/jquery": { + "version": "3.5.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.29.tgz", + "integrity": "sha512-oXQQC9X9MOPRrMhPHHOsXqeQDnWeCDT3PelUIg/Oy8FAbzSZtFHRjc7IpbfFVmpLtJ+UOoywpRsuO5Jxjybyeg==", + "dev": true, + "dependencies": { + "@types/sizzle": "*" + } + }, "node_modules/@types/keyv": { "version": "3.1.4", "license": "MIT", @@ -756,6 +870,12 @@ "@types/node": "*" } }, + "node_modules/@types/sizzle": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "dev": true, @@ -870,6 +990,221 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/archiver-utils/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/archiver/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/archiver/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/archiver/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/archiver/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/archiver/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -883,6 +1218,11 @@ "version": "2.1.3", "license": "ISC" }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "node_modules/asynckit": { "version": "0.4.0", "license": "MIT" @@ -896,11 +1236,21 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, "license": "MIT" }, + "node_modules/bare-events": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", + "optional": true + }, "node_modules/base-64": { "version": "0.1.0" }, @@ -1194,6 +1544,97 @@ "version": "1.2.9", "license": "MIT" }, + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/compress-commons/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/compress-commons/node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/compress-commons/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/compress-commons/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/compress-commons/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/compressible": { "version": "2.0.18", "license": "MIT", @@ -1291,10 +1732,68 @@ "node": ">= 0.8.0" } }, + "node_modules/cookie-session": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.1.0.tgz", + "integrity": "sha512-u73BDmR8QLGcs+Lprs0cfbcAPKl2HnPcjpwRXT41sEV4DRJ2+W0vJEEZkG31ofkx+HZflA70siRIjiTdIodmOQ==", + "dependencies": { + "cookies": "0.9.1", + "debug": "3.2.7", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cookie-session/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/cookie-session/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/cookie-session/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/cookie-signature": { "version": "1.0.6", "license": "MIT" }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "license": "MIT" @@ -1317,9 +1816,96 @@ "node": ">=0.8" } }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/crc32-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/crc32-stream/node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/crc32-stream/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/crc32-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -1505,6 +2091,11 @@ "node": ">=10" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "node_modules/ee-first": { "version": "1.1.1", "license": "MIT" @@ -1752,6 +2343,14 @@ "node": ">=6" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/exif-parser": { "version": "0.1.12" }, @@ -1827,6 +2426,11 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "dev": true, @@ -1950,6 +2554,21 @@ } } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.0", "license": "MIT", @@ -2130,6 +2749,11 @@ "node": ">=12" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, "node_modules/graphemer": { "version": "1.4.0", "dev": true, @@ -2177,6 +2801,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/helmet": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/htmlparser2": { "version": "8.0.2", "funding": [ @@ -2374,6 +3014,17 @@ "node": ">=8" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "license": "MIT", @@ -2390,7 +3041,6 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, "license": "ISC" }, "node_modules/isomorphic-fetch": { @@ -2401,6 +3051,23 @@ "whatwg-fetch": "^3.4.1" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jimp": { "version": "0.22.10", "license": "MIT", @@ -2503,6 +3170,17 @@ "dev": true, "license": "MIT" }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/keyv": { "version": "4.5.3", "license": "MIT", @@ -2510,6 +3188,17 @@ "json-buffer": "3.0.1" } }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, "node_modules/levn": { "version": "0.4.1", "dev": true, @@ -2574,6 +3263,14 @@ "node": ">=8" } }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/md5": { "version": "2.3.0", "license": "BSD-3-Clause", @@ -2662,6 +3359,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.0.0", "license": "MIT" @@ -2739,6 +3444,22 @@ } } }, + "node_modules/node-persist": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-4.0.1.tgz", + "integrity": "sha512-QtRjwAlcOQChQpfG6odtEhxYmA3nS5XYr+bx9JRjwahl1TM3sm9J3CCn51/MI0eoHRb2DrkEsCOFo8sq8jG5sQ==", + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/normalize-url": { "version": "6.1.0", "license": "MIT", @@ -2996,12 +3717,26 @@ }, "node_modules/path-key": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "license": "MIT" @@ -3192,6 +3927,11 @@ ], "license": "MIT" }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/quick-lru": { "version": "5.1.1", "license": "MIT", @@ -3209,6 +3949,11 @@ "node": ">= 0.6" } }, + "node_modules/rate-limiter-flexible": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-5.0.0.tgz", + "integrity": "sha512-ivCyLBwPtR5IRrz+aZnztVwX16ZK3iAjdlW21I/vjHq56at5Zb8eIefDzODg8R7hwPOHpBtb6Pj9Zdmn0nRb8g==" + }, "node_modules/raw-body": { "version": "2.5.2", "license": "MIT", @@ -3268,6 +4013,33 @@ "node": ">= 6" } }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "license": "MIT" @@ -3428,7 +4200,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -3439,7 +4210,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3525,6 +4295,18 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "license": "MIT", @@ -3544,6 +4326,20 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "license": "MIT", @@ -3554,6 +4350,18 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strtok3": { "version": "6.3.0", "license": "MIT", @@ -3580,6 +4388,16 @@ "node": ">=8" } }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -3626,6 +4444,14 @@ "utf8-byte-length": "^1.0.1" } }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "engines": { + "node": ">=0.6.x" + } + }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -3705,8 +4531,13 @@ } }, "node_modules/uuid": { - "version": "9.0.0", - "license": "MIT", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -3770,7 +4601,6 @@ }, "node_modules/which": { "version": "2.0.2", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -3797,6 +4627,23 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "license": "ISC" @@ -3925,6 +4772,84 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zip-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/zip-stream/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/zip-stream/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/zip-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } } } } diff --git a/package.json b/package.json index c8546bd1b..c40d267e4 100644 --- a/package.json +++ b/package.json @@ -4,17 +4,21 @@ "@agnai/web-tokenizers": "^0.1.3", "@dqbd/tiktoken": "^1.0.13", "@zeldafan0225/ai_horde": "^4.0.1", + "archiver": "^7.0.1", "bing-translate-api": "^2.9.1", "body-parser": "^1.20.2", "command-exists": "^1.2.9", "compression": "^1", "cookie-parser": "^1.4.6", + "cookie-session": "^2.1.0", "cors": "^2.8.5", "csrf-csrf": "^2.2.3", "express": "^4.19.2", "form-data": "^4.0.0", "google-translate-api-browser": "^3.0.1", "gpt3-tokenizer": "^1.1.5", + "he": "^1.2.0", + "helmet": "^7.1.0", "ip-matching": "^2.1.2", "ipaddr.js": "^2.0.1", "jimp": "^0.22.10", @@ -22,10 +26,12 @@ "mime-types": "^2.1.35", "multer": "^1.4.5-lts.1", "node-fetch": "^2.6.11", + "node-persist": "^4.0.1", "open": "^8.4.2", "png-chunk-text": "^1.0.0", "png-chunks-encode": "^1.0.0", "png-chunks-extract": "^1.0.0", + "rate-limiter-flexible": "^5.0.0", "response-time": "^2.3.2", "sanitize-filename": "^1.6.3", "sillytavern-transformers": "^2.14.6", @@ -62,7 +68,7 @@ "type": "git", "url": "https://github.com/SillyTavern/SillyTavern.git" }, - "version": "1.11.8", + "version": "1.12.0-preview", "scripts": { "start": "node server.js", "start-multi": "node server.js --disableCsrf", @@ -79,6 +85,7 @@ }, "main": "server.js", "devDependencies": { + "@types/jquery": "^3.5.29", "eslint": "^8.55.0", "jquery": "^3.6.4" } diff --git a/post-install.js b/post-install.js index 406154aae..f787eeba3 100644 --- a/post-install.js +++ b/post-install.js @@ -60,7 +60,8 @@ function convertConfig() { try { console.log(color.blue('Converting config.conf to config.yaml. Your old config.conf will be renamed to config.conf.bak')); const config = require(path.join(process.cwd(), './config.conf')); - fs.renameSync('./config.conf', './config.conf.bak'); + fs.copyFileSync('./config.conf', './config.conf.bak'); + fs.rmSync('./config.conf'); fs.writeFileSync('./config.yaml', yaml.stringify(config)); console.log(color.green('Conversion successful. Please check your config.yaml and fix it if necessary.')); } catch (error) { @@ -106,7 +107,6 @@ function addMissingConfigValues() { */ function createDefaultFiles() { const files = { - settings: './public/settings.json', config: './config.yaml', user: './public/css/user.css', }; @@ -167,29 +167,6 @@ function copyWasmFiles() { } } -/** - * Moves the custom background into settings.json. - */ -function migrateBackground() { - if (!fs.existsSync('./public/css/bg_load.css')) return; - - const bgCSS = fs.readFileSync('./public/css/bg_load.css', 'utf-8'); - const bgMatch = /url\('([^']*)'\)/.exec(bgCSS); - if (!bgMatch) return; - const bgFilename = bgMatch[1].replace('../backgrounds/', ''); - - const settings = fs.readFileSync('./public/settings.json', 'utf-8'); - const settingsJSON = JSON.parse(settings); - if (Object.hasOwn(settingsJSON, 'background')) { - console.log(color.yellow('Both bg_load.css and the "background" setting exist. Please delete bg_load.css manually.')); - return; - } - - settingsJSON.background = { name: bgFilename, url: `url('backgrounds/${bgFilename}')` }; - fs.writeFileSync('./public/settings.json', JSON.stringify(settingsJSON, null, 4)); - fs.rmSync('./public/css/bg_load.css'); -} - try { // 0. Convert config.conf to config.yaml convertConfig(); @@ -199,8 +176,6 @@ try { copyWasmFiles(); // 3. Add missing config values addMissingConfigValues(); - // 4. Migrate bg_load.css to settings.json - migrateBackground(); } catch (error) { console.error(error); } diff --git a/public/NovelAI Settings/.gitkeep b/public/NovelAI Settings/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/public/OpenAI Settings/.gitkeep b/public/OpenAI Settings/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/public/TextGen Settings/.gitkeep b/public/TextGen Settings/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/public/User Avatars/README.md b/public/User Avatars/README.md deleted file mode 100644 index 17c7b8bff..000000000 --- a/public/User Avatars/README.md +++ /dev/null @@ -1 +0,0 @@ -# Put images here to select them as a user persona avatar. diff --git a/public/assets/ambient/.placeholder b/public/assets/ambient/.placeholder deleted file mode 100644 index a4faa1166..000000000 --- a/public/assets/ambient/.placeholder +++ /dev/null @@ -1 +0,0 @@ -Put ambient audio files here. \ No newline at end of file diff --git a/public/assets/bgm/.placeholder b/public/assets/bgm/.placeholder deleted file mode 100644 index 95839f44e..000000000 --- a/public/assets/bgm/.placeholder +++ /dev/null @@ -1 +0,0 @@ -Put bgm audio files here diff --git a/public/assets/blip/.placeholder b/public/assets/blip/.placeholder deleted file mode 100644 index 1ebb7122e..000000000 --- a/public/assets/blip/.placeholder +++ /dev/null @@ -1 +0,0 @@ -Put blip audio files here diff --git a/public/assets/live2d/.placeholder b/public/assets/live2d/.placeholder deleted file mode 100644 index c76c79ab1..000000000 --- a/public/assets/live2d/.placeholder +++ /dev/null @@ -1 +0,0 @@ -Put live2d model folders here diff --git a/public/assets/temp/.placeholder b/public/assets/temp/.placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/public/assets/vrm/animation/.placeholder b/public/assets/vrm/animation/.placeholder deleted file mode 100644 index c7a29571f..000000000 --- a/public/assets/vrm/animation/.placeholder +++ /dev/null @@ -1 +0,0 @@ -Put VRM animation files here diff --git a/public/assets/vrm/model/.placeholder b/public/assets/vrm/model/.placeholder deleted file mode 100644 index 14ce3cf88..000000000 --- a/public/assets/vrm/model/.placeholder +++ /dev/null @@ -1 +0,0 @@ -Put VRM model files here diff --git a/public/characters/.gitkeep b/public/characters/.gitkeep deleted file mode 100644 index 0fa956051..000000000 --- a/public/characters/.gitkeep +++ /dev/null @@ -1,8 +0,0 @@ -# Put PNG character cards here. - -To create a sprites folder, name it the same as your character (NOT the PNG file). - -For example: - -- Character: /characters/Asuka Langley.png -- Sprite: /characters/Asuka Langley/joy.png diff --git a/public/chats/.gitkeep b/public/chats/.gitkeep deleted file mode 100644 index ac488e9b9..000000000 --- a/public/chats/.gitkeep +++ /dev/null @@ -1,5 +0,0 @@ -# Put Chat JSONL files here in subfolders corresponding to character names - -For example: - -- /chats/Robot/chat.jsonl diff --git a/public/context/.gitkeep b/public/context/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/public/css/accounts.css b/public/css/accounts.css new file mode 100644 index 000000000..e5414bf59 --- /dev/null +++ b/public/css/accounts.css @@ -0,0 +1,5 @@ +.userAccount { + border: 1px solid var(--SmartThemeBorderColor); + padding: 5px 10px; + border-radius: 5px; +} diff --git a/public/css/login.css b/public/css/login.css new file mode 100644 index 000000000..94f8e9953 --- /dev/null +++ b/public/css/login.css @@ -0,0 +1,44 @@ +body.login #shadow_popup { + opacity: 1; + display: flex; +} + +body.login .logo { + max-width: 30px; +} + +body.login #logoBlock { + align-items: center; + margin: 0 auto; + gap: 10px; +} + +body.login .userSelect { + display: flex; + flex-direction: column; + color: var(--SmartThemeBodyColor); + border: 1px solid var(--SmartThemeBorderColor); + border-radius: 5px; + padding: 3px 5px; + width: 30%; + cursor: pointer; + margin: 5px 0; + transition: background-color 0.15s ease-in-out; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + overflow: hidden; +} + +body.login .userSelect .userName, +body.login .userSelect .userHandle { + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +body.login .userSelect:hover { + background-color: var(--black30a); +} diff --git a/public/css/st-tailwind.css b/public/css/st-tailwind.css index c911104c1..44664ddfd 100644 --- a/public/css/st-tailwind.css +++ b/public/css/st-tailwind.css @@ -102,6 +102,14 @@ justify-content: space-between; } +.justifySpaceEvenly { + justify-content: space-evenly; +} + +.justifySpaceAround { + justify-content: space-around; +} + .alignitemsflexstart { align-items: flex-start !important; } @@ -491,6 +499,10 @@ textarea:disabled { font-size: calc(var(--mainFontSize) * 1.2) !important; } +.fontsize90p { + font-size: calc(var(--mainFontSize) * 0.9) !important; +} + .fontsize80p { font-size: calc(var(--mainFontSize) * 0.8) !important; } diff --git a/public/group chats/.gitkeep b/public/group chats/.gitkeep deleted file mode 100644 index 535c6dab6..000000000 --- a/public/group chats/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# Put Group Chat JSONL files here diff --git a/public/groups/.gitkeep b/public/groups/.gitkeep deleted file mode 100644 index 0f56f2da9..000000000 --- a/public/groups/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# Put Group JSON files here diff --git a/public/img/logo.png b/public/img/logo.png new file mode 100644 index 000000000..14768e82b Binary files /dev/null and b/public/img/logo.png differ diff --git a/public/index.html b/public/index.html index f405c9d0c..ab7329d76 100644 --- a/public/index.html +++ b/public/index.html @@ -89,6 +89,7 @@ + SillyTavern @@ -3514,7 +3515,21 @@
- +
+ + + +
+
@@ -3957,8 +3972,8 @@ -
diff --git a/public/instruct/.gitkeep b/public/instruct/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/public/lib/epub.min.js b/public/lib/epub.min.js new file mode 100644 index 000000000..60719ba52 --- /dev/null +++ b/public/lib/epub.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("xmldom"),require("JSZip")):"function"==typeof define&&define.amd?define(["xmldom","JSZip"],e):"object"==typeof exports?exports.ePub=e(require("xmldom"),require("JSZip")):t.ePub=e(t.xmldom,t.JSZip)}(window,(function(t,e){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(n,r,function(e){return t[e]}.bind(null,r));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="/dist/",i(i.s=86)}([function(t,e,i){"use strict";i.r(e),i.d(e,"requestAnimationFrame",(function(){return r})),i.d(e,"uuid",(function(){return o})),i.d(e,"documentHeight",(function(){return a})),i.d(e,"isElement",(function(){return h})),i.d(e,"isNumber",(function(){return l})),i.d(e,"isFloat",(function(){return c})),i.d(e,"prefixed",(function(){return u})),i.d(e,"defaults",(function(){return d})),i.d(e,"extend",(function(){return f})),i.d(e,"insert",(function(){return p})),i.d(e,"locationOf",(function(){return g})),i.d(e,"indexOfSorted",(function(){return v})),i.d(e,"bounds",(function(){return m})),i.d(e,"borders",(function(){return y})),i.d(e,"nodeBounds",(function(){return b})),i.d(e,"windowBounds",(function(){return w})),i.d(e,"indexOfNode",(function(){return x})),i.d(e,"indexOfTextNode",(function(){return E})),i.d(e,"indexOfElementNode",(function(){return S})),i.d(e,"isXml",(function(){return _})),i.d(e,"createBlob",(function(){return O})),i.d(e,"createBlobUrl",(function(){return C})),i.d(e,"revokeBlobUrl",(function(){return T})),i.d(e,"createBase64Url",(function(){return k})),i.d(e,"type",(function(){return R})),i.d(e,"parse",(function(){return L})),i.d(e,"qs",(function(){return I})),i.d(e,"qsa",(function(){return j})),i.d(e,"qsp",(function(){return N})),i.d(e,"sprint",(function(){return A})),i.d(e,"treeWalker",(function(){return P})),i.d(e,"walk",(function(){return D})),i.d(e,"blob2base64",(function(){return z})),i.d(e,"defer",(function(){return B})),i.d(e,"querySelectorByType",(function(){return q})),i.d(e,"findChildren",(function(){return M})),i.d(e,"parents",(function(){return U})),i.d(e,"filterChildren",(function(){return F})),i.d(e,"getParentByTagName",(function(){return W})),i.d(e,"RangeObject",(function(){return H}));i(24),i(14),i(20);var n=i(38);const r="undefined"!=typeof window&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame),s="undefined"!=typeof URL?URL:"undefined"!=typeof window?window.URL||window.webkitURL||window.mozURL:void 0;function o(){var t=(new Date).getTime();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){var i=(t+16*Math.random())%16|0;return t=Math.floor(t/16),("x"==e?i:7&i|8).toString(16)}))}function a(){return Math.max(document.documentElement.clientHeight,document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight)}function h(t){return!(!t||1!=t.nodeType)}function l(t){return!isNaN(parseFloat(t))&&isFinite(t)}function c(t){let e=parseFloat(t);return!1!==l(t)&&("string"==typeof t&&t.indexOf(".")>-1||Math.floor(e)!==e)}function u(t){var e=["-webkit-","-webkit-","-moz-","-o-","-ms-"],i=t.toLowerCase(),n=["Webkit","webkit","Moz","O","ms"].length;if("undefined"==typeof document||void 0!==document.body.style[i])return t;for(var r=0;re?1:t=0?h:h+1:0===s?h:-1===s?g(t,e,i,h,a):g(t,e,i,o,h))}function v(t,e,i,n,r){var s,o=n||0,a=r||e.length,h=parseInt(o+(a-o)/2);return i||(i=function(t,e){return t>e?1:t-1}function O(t,e){return new Blob([t],{type:e})}function C(t,e){var i=O(t,e);return s.createObjectURL(i)}function T(t){return s.revokeObjectURL(t)}function k(t,e){if("string"==typeof t)return"data:"+e+";base64,"+btoa(encodeURIComponent(t))}function R(t){return Object.prototype.toString.call(t).slice(8,-1)}function L(t,e,i){var r;return r="undefined"==typeof DOMParser||i?n.DOMParser:DOMParser,65279===t.charCodeAt(0)&&(t=t.slice(1)),(new r).parseFromString(t,e)}function I(t,e){var i;if(!t)throw new Error("No Element Provided");return void 0!==t.querySelector?t.querySelector(e):(i=t.getElementsByTagName(e)).length?i[0]:void 0}function j(t,e){return void 0!==t.querySelector?t.querySelectorAll(e):t.getElementsByTagName(e)}function N(t,e,i){var n,r;if(void 0!==t.querySelector){for(var s in e+="[",i)e+=s+"~='"+i[s]+"'";return e+="]",t.querySelector(e)}if(n=t.getElementsByTagName(e),r=Array.prototype.slice.call(n,0).filter((function(t){for(var e in i)if(t.getAttribute(e)===i[e])return!0;return!1})))return r[0]}function A(t,e){void 0!==(t.ownerDocument||t).createTreeWalker?P(t,e,NodeFilter.SHOW_TEXT):D(t,(function(t){t&&3===t.nodeType&&e(t)}))}function P(t,e,i){var n=document.createTreeWalker(t,i,null,!1);let r;for(;r=n.nextNode();)e(r)}function D(t,e){if(e(t))return!0;if(t=t.firstChild)do{if(D(t,e))return!0;t=t.nextSibling}while(t)}function z(t){return new Promise((function(e,i){var n=new FileReader;n.readAsDataURL(t),n.onloadend=function(){e(n.result)}}))}function B(){this.resolve=null,this.reject=null,this.id=o(),this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e}),Object.freeze(this)}function q(t,e,i){var n;if(void 0!==t.querySelector&&(n=t.querySelector(`${e}[*|type="${i}"]`)),n&&0!==n.length)return n;n=j(t,e);for(var r=0;r1&&(e=n[1],i.terminal=this.parseTerminal(e)),""===r[0]&&r.shift(),i.steps=r.map(function(t){return this.parseStep(t)}.bind(this)),i}parseStep(t){var e,i,n,r,s;if((r=t.match(/\[(.*)\]/))&&r[1]&&(s=r[1]),i=parseInt(t),!isNaN(i))return i%2==0?(e="element",n=i/2-1):(e="text",n=(i-1)/2),{type:e,index:n,id:s||null}}parseTerminal(t){var e,i,r=t.match(/\[(.*)\]/);return r&&r[1]?(e=parseInt(t.split("[")[0]),i=r[1]):e=parseInt(t),Object(n.isNumber)(e)||(e=null),{offset:e,assertion:i}}getChapterComponent(t){return t.split("!")[0]}getPathComponent(t){var e=t.split("!");if(e[1]){return e[1].split(",")[0]}}getRange(t){var e=t.split(",");return 3===e.length&&[e[1],e[2]]}getCharecterOffsetComponent(t){return t.split(":")[1]||""}joinSteps(t){return t?t.map((function(t){var e="";return"element"===t.type&&(e+=2*(t.index+1)),"text"===t.type&&(e+=1+2*t.index),t.id&&(e+="["+t.id+"]"),e})).join("/"):""}segmentString(t){var e="/";return e+=this.joinSteps(t.steps),t.terminal&&null!=t.terminal.offset&&(e+=":"+t.terminal.offset),t.terminal&&null!=t.terminal.assertion&&(e+="["+t.terminal.assertion+"]"),e}toString(){var t="epubcfi(";return t+=this.segmentString(this.base),t+="!",t+=this.segmentString(this.path),this.range&&this.start&&(t+=",",t+=this.segmentString(this.start)),this.range&&this.end&&(t+=",",t+=this.segmentString(this.end)),t+=")"}compare(t,e){var i,n,s,o;if("string"==typeof t&&(t=new r(t)),"string"==typeof e&&(e=new r(e)),t.spinePos>e.spinePos)return 1;if(t.spinePosn[a].index)return 1;if(i[a].indexo.offset?1:s.offset=0&&(r.terminal.offset=e,"text"!=r.steps[r.steps.length-1].type&&r.steps.push({type:"text",index:0})),r}equalStep(t,e){return!(!t||!e)&&(t.index===e.index&&t.id===e.id&&t.type===e.type)}fromRange(t,e,i){var n={range:!1,base:{},path:{},start:null,end:null},r=t.startContainer,s=t.endContainer,o=t.startOffset,a=t.endOffset,h=!1;if(i&&(h=null!=r.ownerDocument.querySelector("."+i)),"string"==typeof e?(n.base=this.parseComponent(e),n.spinePos=n.base.steps[1].index):"object"==typeof e&&(n.base=e),t.collapsed)h&&(o=this.patchOffset(r,o,i)),n.path=this.pathTo(r,o,i);else{n.range=!0,h&&(o=this.patchOffset(r,o,i)),n.start=this.pathTo(r,o,i),h&&(a=this.patchOffset(s,a,i)),n.end=this.pathTo(s,a,i),n.path={steps:[],terminal:null};var l,c=n.start.steps.length;for(l=0;l0&&3===r&&3===s?o[n]=a:e===r&&(a+=1,o[n]=a),s=r;return o}position(t){var e,i;return 1===t.nodeType?((e=t.parentNode.children)||(e=Object(n.findChildren)(t.parentNode)),i=Array.prototype.indexOf.call(e,t)):i=(e=this.textNodes(t.parentNode)).indexOf(t),i}filteredPosition(t,e){var i,n;return 1===t.nodeType?(i=t.parentNode.children,n=this.normalizedMap(i,1,e)):(i=t.parentNode.childNodes,t.parentNode.classList.contains(e)&&(i=(t=t.parentNode).parentNode.childNodes),n=this.normalizedMap(i,3,e)),n[Array.prototype.indexOf.call(i,t)]}stepsToXpath(t){var e=[".","*"];return t.forEach((function(t){var i=t.index+1;t.id?e.push("*[position()="+i+" and @id='"+t.id+"']"):"text"===t.type?e.push("text()["+i+"]"):e.push("*["+i+"]")})),e.join("/")}stepsToQuerySelector(t){var e=["html"];return t.forEach((function(t){var i=t.index+1;t.id?e.push("#"+t.id):"text"===t.type||e.push("*:nth-child("+i+")")})),e.join(">")}textNodes(t,e){return Array.prototype.slice.call(t.childNodes).filter((function(t){return 3===t.nodeType||!(!e||!t.classList.contains(e))}))}walkToNode(t,e,i){var r,s,o=e||document,a=o.documentElement,h=t.length;for(s=0;s(s=(r=a[t]).textContent.length))){o=1===r.nodeType?r.childNodes[0]:r;break}e-=s}}return{container:o,offset:e}}toRange(t,e){var i,r,s,o,a,h,l,c,u=t||document,d=!!e&&null!=u.querySelector("."+e);if(i=void 0!==u.createRange?u.createRange():new n.RangeObject,this.range?(r=this.start,h=this.path.steps.concat(r.steps),o=this.findNode(h,u,d?e:null),s=this.end,l=this.path.steps.concat(s.steps),a=this.findNode(l,u,d?e:null)):(r=this.path,h=this.path.steps,o=this.findNode(this.path.steps,u,d?e:null)),!o)return console.log("No startContainer found for",this.toString()),null;try{null!=r.terminal.offset?i.setStart(o,r.terminal.offset):i.setStart(o,0)}catch(t){c=this.fixMiss(h,r.terminal.offset,u,d?e:null),i.setStart(c.container,c.offset)}if(a)try{null!=s.terminal.offset?i.setEnd(a,s.terminal.offset):i.setEnd(a,0)}catch(t){c=this.fixMiss(l,this.end.terminal.offset,u,d?e:null),i.setEnd(c.container,c.offset)}return i}isCfiString(t){return"string"==typeof t&&0===t.indexOf("epubcfi(")&&")"===t[t.length-1]}generateChapterComponent(t,e,i){var n="/"+2*(t+1)+"/";return n+=2*(parseInt(e)+1),i&&(n+="["+i+"]"),n}collapse(t){this.range&&(this.range=!1,t?(this.path.steps=this.path.steps.concat(this.start.steps),this.path.terminal=this.start.terminal):(this.path.steps=this.path.steps.concat(this.end.steps),this.path.terminal=this.end.terminal))}}e.a=r},function(t,e,i){"use strict";var n,r,s,o,a,h,l,c=i(108),u=i(122),d=Function.prototype.apply,f=Function.prototype.call,p=Object.create,g=Object.defineProperty,v=Object.defineProperties,m=Object.prototype.hasOwnProperty,y={configurable:!0,enumerable:!1,writable:!0};r=function(t,e){var i,r;return u(e),r=this,n.call(this,t,i=function(){s.call(r,t,i),d.call(e,this,arguments)}),i.__eeOnceListener__=e,this},a={on:n=function(t,e){var i;return u(e),m.call(this,"__ee__")?i=this.__ee__:(i=y.value=p(null),g(this,"__ee__",y),y.value=null),i[t]?"object"==typeof i[t]?i[t].push(e):i[t]=[i[t],e]:i[t]=e,this},once:r,off:s=function(t,e){var i,n,r,s;if(u(e),!m.call(this,"__ee__"))return this;if(!(i=this.__ee__)[t])return this;if("object"==typeof(n=i[t]))for(s=0;r=n[s];++s)r!==e&&r.__eeOnceListener__!==e||(2===n.length?i[t]=n[s?0:1]:n.splice(s,1));else n!==e&&n.__eeOnceListener__!==e||delete i[t];return this},emit:o=function(t){var e,i,n,r,s;if(m.call(this,"__ee__")&&(r=this.__ee__[t]))if("object"==typeof r){for(i=arguments.length,s=new Array(i-1),e=1;e-1&&(t=new URL(t).pathname),e=this.parse(t),this.path=t,this.isDirectory(t)?this.directory=t:this.directory=e.dir+"/",this.filename=e.base,this.extension=e.ext.slice(1)}parse(t){return r.a.parse(t)}isAbsolute(t){return r.a.isAbsolute(t||this.path)}isDirectory(t){return"/"===t.charAt(t.length-1)}resolve(t){return r.a.resolve(this.directory,t)}relative(t){return t&&t.indexOf("://")>-1?t:r.a.relative(this.directory,t)}splitPath(t){return this.splitPathRe.exec(t).slice(1)}toString(){return this.path}}},function(t,e,i){"use strict";i(14),i(20);var n=i(4),r=i(9),s=i.n(r);e.a=class{constructor(t,e){var i=t.indexOf("://")>-1,r=t;if(this.Url=void 0,this.href=t,this.protocol="",this.origin="",this.hash="",this.hash="",this.search="",this.base=e,!i&&!1!==e&&"string"!=typeof e&&window&&window.location&&(this.base=window.location.href),i||this.base)try{this.base?this.Url=new URL(t,this.base):this.Url=new URL(t),this.href=this.Url.href,this.protocol=this.Url.protocol,this.origin=this.Url.origin,this.hash=this.Url.hash,this.search=this.Url.search,r=this.Url.pathname+(this.Url.search?this.Url.search:"")}catch(t){this.Url=void 0,this.base&&(r=new n.a(this.base).resolve(r))}this.Path=new n.a(r),this.directory=this.Path.directory,this.filename=this.Path.filename,this.extension=this.Path.extension}path(){return this.Path}resolve(t){var e;return t.indexOf("://")>-1?t:(e=s.a.resolve(this.directory,t),this.origin+e)}relative(t){return s.a.relative(t,this.directory)}toString(){return this.href}}},function(t,e,i){"use strict";i(14);e.a=class{constructor(t){this.context=t||this,this.hooks=[]}register(){for(var t=0;t2){for(var a=n.length-1,h=a;h>=0&&47!==n.charCodeAt(h);--h);if(h!==a){n=-1===h?"":n.slice(0,h),r=o,s=0;continue}}else if(2===n.length||1===n.length){n="",r=o,s=0;continue}e&&(n.length>0?n+="/..":n="..")}else n.length>0?n+="/"+t.slice(r+1,o):n=t.slice(r+1,o);r=o,s=0}else 46===i&&-1!==s?++s:s=-1}return n}var o={resolve:function(){for(var t,e="",i=!1,o=arguments.length-1;o>=-1&&!i;o--){var a;o>=0?a=arguments[o]:(void 0===t&&(t=n.cwd()),a=t),r(a),0!==a.length&&(e=a+"/"+e,i=47===a.charCodeAt(0))}return e=s(e,!i),i?e.length>0?"/"+e:"/":e.length>0?e:"."},normalize:function(t){if(r(t),0===t.length)return".";var e=47===t.charCodeAt(0),i=47===t.charCodeAt(t.length-1);return 0!==(t=s(t,!e)).length||e||(t="."),t.length>0&&i&&(t+="/"),e?"/"+t:t},isAbsolute:function(t){return r(t),t.length>0&&47===t.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var t,e=0;e0&&(void 0===t?t=i:t+="/"+i)}return void 0===t?".":o.normalize(t)},relative:function(t,e){if(r(t),r(e),t===e)return"";if((t=o.resolve(t))===(e=o.resolve(e)))return"";for(var i=1;il){if(47===e.charCodeAt(a+u))return e.slice(a+u+1);if(0===u)return e.slice(a+u)}else s>l&&(47===t.charCodeAt(i+u)?c=u:0===u&&(c=0));break}var d=t.charCodeAt(i+u);if(d!==e.charCodeAt(a+u))break;47===d&&(c=u)}var f="";for(u=i+c+1;u<=n;++u)u!==n&&47!==t.charCodeAt(u)||(0===f.length?f+="..":f+="/..");return f.length>0?f+e.slice(a+c):(a+=c,47===e.charCodeAt(a)&&++a,e.slice(a))},_makeLong:function(t){return t},dirname:function(t){if(r(t),0===t.length)return".";for(var e=t.charCodeAt(0),i=47===e,n=-1,s=!0,o=t.length-1;o>=1;--o)if(47===(e=t.charCodeAt(o))){if(!s){n=o;break}}else s=!1;return-1===n?i?"/":".":i&&1===n?"//":t.slice(0,n)},basename:function(t,e){if(void 0!==e&&"string"!=typeof e)throw new TypeError('"ext" argument must be a string');r(t);var i,n=0,s=-1,o=!0;if(void 0!==e&&e.length>0&&e.length<=t.length){if(e.length===t.length&&e===t)return"";var a=e.length-1,h=-1;for(i=t.length-1;i>=0;--i){var l=t.charCodeAt(i);if(47===l){if(!o){n=i+1;break}}else-1===h&&(o=!1,h=i+1),a>=0&&(l===e.charCodeAt(a)?-1==--a&&(s=i):(a=-1,s=h))}return n===s?s=h:-1===s&&(s=t.length),t.slice(n,s)}for(i=t.length-1;i>=0;--i)if(47===t.charCodeAt(i)){if(!o){n=i+1;break}}else-1===s&&(o=!1,s=i+1);return-1===s?"":t.slice(n,s)},extname:function(t){r(t);for(var e=-1,i=0,n=-1,s=!0,o=0,a=t.length-1;a>=0;--a){var h=t.charCodeAt(a);if(47!==h)-1===n&&(s=!1,n=a+1),46===h?-1===e?e=a:1!==o&&(o=1):-1!==e&&(o=-1);else if(!s){i=a+1;break}}return-1===e||-1===n||0===o||1===o&&e===n-1&&e===i+1?"":t.slice(e,n)},format:function(t){if(null===t||"object"!=typeof t)throw new TypeError('Parameter "pathObject" must be an object, not '+typeof t);return function(t,e){var i=e.dir||e.root,n=e.base||(e.name||"")+(e.ext||"");return i?i===e.root?i+n:i+t+n:n}("/",t)},parse:function(t){r(t);var e={root:"",dir:"",base:"",ext:"",name:""};if(0===t.length)return e;var i,n=t.charCodeAt(0),s=47===n;s?(e.root="/",i=1):i=0;for(var o=-1,a=0,h=-1,l=!0,c=t.length-1,u=0;c>=i;--c)if(47!==(n=t.charCodeAt(c)))-1===h&&(l=!1,h=c+1),46===n?-1===o?o=c:1!==u&&(u=1):-1!==o&&(u=-1);else if(!l){a=c+1;break}return-1===o||-1===h||0===u||1===u&&o===h-1&&o===a+1?-1!==h&&(e.base=e.name=0===a&&s?t.slice(1,h):t.slice(a,h)):(0===a&&s?(e.name=t.slice(1,o),e.base=t.slice(1,h)):(e.name=t.slice(a,o),e.base=t.slice(a,h)),e.ext=t.slice(o,h)),a>0?e.dir=t.slice(0,a-1):s&&(e.dir="/"),e},sep:"/",delimiter:":",posix:null};t.exports=o},function(t,e){var i={}.hasOwnProperty;t.exports=function(t,e){return i.call(t,e)}},function(t,e,i){"use strict";i.d(e,"a",(function(){return s})),i.d(e,"b",(function(){return o})),i.d(e,"d",(function(){return a})),i.d(e,"c",(function(){return h})),i.d(e,"e",(function(){return l}));i(24);var n=i(0),r=i(5);i(4);function s(t,e){var i,r,s=e.url,o=s.indexOf("://")>-1;t&&(r=Object(n.qs)(t,"head"),(i=Object(n.qs)(r,"base"))||(i=t.createElement("base"),r.insertBefore(i,r.firstChild)),!o&&window&&window.location&&(s=window.location.origin+s),i.setAttribute("href",s))}function o(t,e){var i,r,s=e.canonical;t&&(i=Object(n.qs)(t,"head"),(r=Object(n.qs)(i,"link[rel='canonical']"))?r.setAttribute("href",s):((r=t.createElement("link")).setAttribute("rel","canonical"),r.setAttribute("href",s),i.appendChild(r)))}function a(t,e){var i,r,s=e.idref;t&&(i=Object(n.qs)(t,"head"),(r=Object(n.qs)(i,"link[property='dc.identifier']"))?r.setAttribute("content",s):((r=t.createElement("meta")).setAttribute("name","dc.identifier"),r.setAttribute("content",s),i.appendChild(r)))}function h(t,e){var i=t.querySelectorAll("a[href]");if(i.length)for(var s=Object(n.qs)(t.ownerDocument,"base"),o=s?s.getAttribute("href"):void 0,a=function(t){var i=t.getAttribute("href");if(0!==i.indexOf("mailto:"))if(i.indexOf("://")>-1)t.setAttribute("target","_blank");else{var n;try{n=new r.a(i,o)}catch(t){}t.onclick=function(){return n&&n.hash?e(n.Path.path+n.hash):e(n?n.Path.path:i),!1}}}.bind(this),h=0;h4)return t;for(i=[],n=0;n1&&"0"==r.charAt(0)&&(s=R.test(r)?16:8,r=r.slice(8==s?1:2)),""===r)o=0;else{if(!(10==s?I:8==s?L:j).test(r))return t;o=parseInt(r,s)}i.push(o)}for(n=0;n=O(256,5-e))return null}else if(o>255)return null;for(a=i.pop(),n=0;n6)return;for(n=0;d();){if(r=null,n>0){if(!("."==d()&&n<4))return;u++}if(!k.test(d()))return;for(;k.test(d());){if(s=parseInt(d(),10),null===r)r=s;else{if(0==r)return;r=10*r+s}if(r>255)return;u++}h[l]=256*h[l]+r,2!=++n&&4!=n||l++}if(4!=n)return;break}if(":"==d()){if(u++,!d())return}else if(d())return;h[l++]=e}else{if(null!==c)return;u++,c=++l}}if(null!==c)for(o=l-c,l=7;0!=l&&o>0;)a=h[l],h[l--]=h[c+o-1],h[c+--o]=a;else if(8!=l)return;return h},M=function(t){var e,i,n,r;if("number"==typeof t){for(e=[],i=0;i<4;i++)e.unshift(t%256),t=_(t/256);return e.join(".")}if("object"==typeof t){for(e="",n=function(t){for(var e=null,i=1,n=null,r=0,s=0;s<8;s++)0!==t[s]?(r>i&&(e=n,i=r),n=null,r=0):(null===n&&(n=s),++r);return r>i&&(e=n,i=r),e}(t),i=0;i<8;i++)r&&0===t[i]||(r&&(r=!1),n===i?(e+=i?":":"::",r=!0):(e+=t[i].toString(16),i<7&&(e+=":")));return"["+e+"]"}return t},U={},F=d({},U,{" ":1,'"':1,"<":1,">":1,"`":1}),W=d({},F,{"#":1,"?":1,"{":1,"}":1}),H=d({},W,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),V=function(t,e){var i=p(t,0);return i>32&&i<127&&!u(e,t)?t:encodeURIComponent(t)},X={ftp:21,file:null,http:80,https:443,ws:80,wss:443},G=function(t){return u(X,t.scheme)},Y=function(t){return""!=t.username||""!=t.password},$=function(t){return!t.host||t.cannotBeABaseURL||"file"==t.scheme},K=function(t,e){var i;return 2==t.length&&C.test(t.charAt(0))&&(":"==(i=t.charAt(1))||!e&&"|"==i)},Z=function(t){var e;return t.length>1&&K(t.slice(0,2))&&(2==t.length||"/"===(e=t.charAt(2))||"\\"===e||"?"===e||"#"===e)},J=function(t){var e=t.path,i=e.length;!i||"file"==t.scheme&&1==i&&K(e[0],!0)||e.pop()},Q=function(t){return"."===t||"%2e"===t.toLowerCase()},tt={},et={},it={},nt={},rt={},st={},ot={},at={},ht={},lt={},ct={},ut={},dt={},ft={},pt={},gt={},vt={},mt={},yt={},bt={},wt={},xt=function(t,e,i,r){var s,o,a,h,l,c=i||tt,d=0,p="",g=!1,v=!1,m=!1;for(i||(t.scheme="",t.username="",t.password="",t.host=null,t.port=null,t.path=[],t.query=null,t.fragment=null,t.cannotBeABaseURL=!1,e=e.replace(P,"")),e=e.replace(D,""),s=f(e);d<=s.length;){switch(o=s[d],c){case tt:if(!o||!C.test(o)){if(i)return"Invalid scheme";c=it;continue}p+=o.toLowerCase(),c=et;break;case et:if(o&&(T.test(o)||"+"==o||"-"==o||"."==o))p+=o.toLowerCase();else{if(":"!=o){if(i)return"Invalid scheme";p="",c=it,d=0;continue}if(i&&(G(t)!=u(X,p)||"file"==p&&(Y(t)||null!==t.port)||"file"==t.scheme&&!t.host))return;if(t.scheme=p,i)return void(G(t)&&X[t.scheme]==t.port&&(t.port=null));p="","file"==t.scheme?c=ft:G(t)&&r&&r.scheme==t.scheme?c=nt:G(t)?c=at:"/"==s[d+1]?(c=rt,d++):(t.cannotBeABaseURL=!0,t.path.push(""),c=yt)}break;case it:if(!r||r.cannotBeABaseURL&&"#"!=o)return"Invalid scheme";if(r.cannotBeABaseURL&&"#"==o){t.scheme=r.scheme,t.path=r.path.slice(),t.query=r.query,t.fragment="",t.cannotBeABaseURL=!0,c=wt;break}c="file"==r.scheme?ft:st;continue;case nt:if("/"!=o||"/"!=s[d+1]){c=st;continue}c=ht,d++;break;case rt:if("/"==o){c=lt;break}c=mt;continue;case st:if(t.scheme=r.scheme,o==n)t.username=r.username,t.password=r.password,t.host=r.host,t.port=r.port,t.path=r.path.slice(),t.query=r.query;else if("/"==o||"\\"==o&&G(t))c=ot;else if("?"==o)t.username=r.username,t.password=r.password,t.host=r.host,t.port=r.port,t.path=r.path.slice(),t.query="",c=bt;else{if("#"!=o){t.username=r.username,t.password=r.password,t.host=r.host,t.port=r.port,t.path=r.path.slice(),t.path.pop(),c=mt;continue}t.username=r.username,t.password=r.password,t.host=r.host,t.port=r.port,t.path=r.path.slice(),t.query=r.query,t.fragment="",c=wt}break;case ot:if(!G(t)||"/"!=o&&"\\"!=o){if("/"!=o){t.username=r.username,t.password=r.password,t.host=r.host,t.port=r.port,c=mt;continue}c=lt}else c=ht;break;case at:if(c=ht,"/"!=o||"/"!=p.charAt(d+1))continue;d++;break;case ht:if("/"!=o&&"\\"!=o){c=lt;continue}break;case lt:if("@"==o){g&&(p="%40"+p),g=!0,a=f(p);for(var y=0;y65535)return"Invalid port";t.port=G(t)&&x===X[t.scheme]?null:x,p=""}if(i)return;c=vt;continue}return"Invalid port"}p+=o;break;case ft:if(t.scheme="file","/"==o||"\\"==o)c=pt;else{if(!r||"file"!=r.scheme){c=mt;continue}if(o==n)t.host=r.host,t.path=r.path.slice(),t.query=r.query;else if("?"==o)t.host=r.host,t.path=r.path.slice(),t.query="",c=bt;else{if("#"!=o){Z(s.slice(d).join(""))||(t.host=r.host,t.path=r.path.slice(),J(t)),c=mt;continue}t.host=r.host,t.path=r.path.slice(),t.query=r.query,t.fragment="",c=wt}}break;case pt:if("/"==o||"\\"==o){c=gt;break}r&&"file"==r.scheme&&!Z(s.slice(d).join(""))&&(K(r.path[0],!0)?t.path.push(r.path[0]):t.host=r.host),c=mt;continue;case gt:if(o==n||"/"==o||"\\"==o||"?"==o||"#"==o){if(!i&&K(p))c=mt;else if(""==p){if(t.host="",i)return;c=vt}else{if(h=z(t,p))return h;if("localhost"==t.host&&(t.host=""),i)return;p="",c=vt}continue}p+=o;break;case vt:if(G(t)){if(c=mt,"/"!=o&&"\\"!=o)continue}else if(i||"?"!=o)if(i||"#"!=o){if(o!=n&&(c=mt,"/"!=o))continue}else t.fragment="",c=wt;else t.query="",c=bt;break;case mt:if(o==n||"/"==o||"\\"==o&&G(t)||!i&&("?"==o||"#"==o)){if(".."===(l=(l=p).toLowerCase())||"%2e."===l||".%2e"===l||"%2e%2e"===l?(J(t),"/"==o||"\\"==o&&G(t)||t.path.push("")):Q(p)?"/"==o||"\\"==o&&G(t)||t.path.push(""):("file"==t.scheme&&!t.path.length&&K(p)&&(t.host&&(t.host=""),p=p.charAt(0)+":"),t.path.push(p)),p="","file"==t.scheme&&(o==n||"?"==o||"#"==o))for(;t.path.length>1&&""===t.path[0];)t.path.shift();"?"==o?(t.query="",c=bt):"#"==o&&(t.fragment="",c=wt)}else p+=V(o,W);break;case yt:"?"==o?(t.query="",c=bt):"#"==o?(t.fragment="",c=wt):o!=n&&(t.path[0]+=V(o,U));break;case bt:i||"#"!=o?o!=n&&("'"==o&&G(t)?t.query+="%27":t.query+="#"==o?"%23":V(o,U)):(t.fragment="",c=wt);break;case wt:o!=n&&(t.fragment+=V(o,F))}d++}},Et=function(t){var e,i,n=c(this,Et,"URL"),r=arguments.length>1?arguments[1]:void 0,o=String(t),a=E(n,{type:"URL"});if(void 0!==r)if(r instanceof Et)e=S(r);else if(i=xt(e={},String(r)))throw TypeError(i);if(i=xt(a,o,null,e))throw TypeError(i);var h=a.searchParams=new w,l=x(h);l.updateSearchParams(a.query),l.updateURL=function(){a.query=String(h)||null},s||(n.href=_t.call(n),n.origin=Ot.call(n),n.protocol=Ct.call(n),n.username=Tt.call(n),n.password=kt.call(n),n.host=Rt.call(n),n.hostname=Lt.call(n),n.port=It.call(n),n.pathname=jt.call(n),n.search=Nt.call(n),n.searchParams=At.call(n),n.hash=Pt.call(n))},St=Et.prototype,_t=function(){var t=S(this),e=t.scheme,i=t.username,n=t.password,r=t.host,s=t.port,o=t.path,a=t.query,h=t.fragment,l=e+":";return null!==r?(l+="//",Y(t)&&(l+=i+(n?":"+n:"")+"@"),l+=M(r),null!==s&&(l+=":"+s)):"file"==e&&(l+="//"),l+=t.cannotBeABaseURL?o[0]:o.length?"/"+o.join("/"):"",null!==a&&(l+="?"+a),null!==h&&(l+="#"+h),l},Ot=function(){var t=S(this),e=t.scheme,i=t.port;if("blob"==e)try{return new URL(e.path[0]).origin}catch(t){return"null"}return"file"!=e&&G(t)?e+"://"+M(t.host)+(null!==i?":"+i:""):"null"},Ct=function(){return S(this).scheme+":"},Tt=function(){return S(this).username},kt=function(){return S(this).password},Rt=function(){var t=S(this),e=t.host,i=t.port;return null===e?"":null===i?M(e):M(e)+":"+i},Lt=function(){var t=S(this).host;return null===t?"":M(t)},It=function(){var t=S(this).port;return null===t?"":String(t)},jt=function(){var t=S(this),e=t.path;return t.cannotBeABaseURL?e[0]:e.length?"/"+e.join("/"):""},Nt=function(){var t=S(this).query;return t?"?"+t:""},At=function(){return S(this).searchParams},Pt=function(){var t=S(this).fragment;return t?"#"+t:""},Dt=function(t,e){return{get:t,set:e,configurable:!0,enumerable:!0}};if(s&&h(St,{href:Dt(_t,(function(t){var e=S(this),i=String(t),n=xt(e,i);if(n)throw TypeError(n);x(e.searchParams).updateSearchParams(e.query)})),origin:Dt(Ot),protocol:Dt(Ct,(function(t){var e=S(this);xt(e,String(t)+":",tt)})),username:Dt(Tt,(function(t){var e=S(this),i=f(String(t));if(!$(e)){e.username="";for(var n=0;n{this._q.length?this.dequeue().then(function(){this.run()}.bind(this)):(this.defered.resolve(),this.running=void 0)}),1==this.paused&&(this.paused=!1),this.defered.promise}flush(){return this.running?this.running:this._q.length?(this.running=this.dequeue().then(function(){return this.running=void 0,this.flush()}.bind(this)),this.running):void 0}clear(){this._q=[]}length(){return this._q.length}pause(){this.paused=!0}stop(){this._q=[],this.running=!1,this.paused=!0}}},function(t,e,i){"use strict";var n=i(3),r=i.n(n),s=i(0);function o(){var t="reverse",e=function(){var t=document.createElement("div");t.dir="rtl",t.style.position="fixed",t.style.width="1px",t.style.height="1px",t.style.top="0px",t.style.left="0px",t.style.overflow="hidden";var e=document.createElement("div");e.style.width="2px";var i=document.createElement("span");i.style.width="1px",i.style.display="inline-block";var n=document.createElement("span");return n.style.width="1px",n.style.display="inline-block",e.appendChild(i),e.appendChild(n),t.appendChild(e),t}();return document.body.appendChild(e),e.scrollLeft>0?t="default":"undefined"!=typeof Element&&Element.prototype.scrollIntoView?(e.children[0].children[1].scrollIntoView(),e.scrollLeft<0&&(t="negative")):(e.scrollLeft=1,0===e.scrollLeft&&(t="negative")),document.body.removeChild(e),t}var a=i(23),h=i(21),l=i(84),c=i.n(l);var u=class{constructor(t){this.settings=t||{},this.id="epubjs-container-"+Object(s.uuid)(),this.container=this.create(this.settings),this.settings.hidden&&(this.wrapper=this.wrap(this.container))}create(t){let e=t.height,i=t.width,n=t.overflow||!1,r=t.axis||"vertical",o=t.direction;Object(s.extend)(this.settings,t),t.height&&Object(s.isNumber)(t.height)&&(e=t.height+"px"),t.width&&Object(s.isNumber)(t.width)&&(i=t.width+"px");let a=document.createElement("div");return a.id=this.id,a.classList.add("epub-container"),a.style.wordSpacing="0",a.style.lineHeight="0",a.style.verticalAlign="top",a.style.position="relative","horizontal"===r&&(a.style.display="flex",a.style.flexDirection="row",a.style.flexWrap="nowrap"),i&&(a.style.width=i),e&&(a.style.height=e),n&&("scroll"===n&&"vertical"===r?(a.style["overflow-y"]=n,a.style["overflow-x"]="hidden"):"scroll"===n&&"horizontal"===r?(a.style["overflow-y"]="hidden",a.style["overflow-x"]=n):a.style.overflow=n),o&&(a.dir=o,a.style.direction=o),o&&this.settings.fullsize&&(document.body.style.direction=o),a}wrap(t){var e=document.createElement("div");return e.style.visibility="hidden",e.style.overflow="hidden",e.style.width="0",e.style.height="0",e.appendChild(t),e}getElement(t){var e;if(Object(s.isElement)(t)?e=t:"string"==typeof t&&(e=document.getElementById(t)),!e)throw new Error("Not an Element");return e}attachTo(t){var e,i=this.getElement(t);if(i)return e=this.settings.hidden?this.wrapper:this.container,i.appendChild(e),this.element=i,i}getContainer(){return this.container}onResize(t){Object(s.isNumber)(this.settings.width)&&Object(s.isNumber)(this.settings.height)||(this.resizeFunc=c()(t,50),window.addEventListener("resize",this.resizeFunc,!1))}onOrientationChange(t){this.orientationChangeFunc=t,window.addEventListener("orientationchange",this.orientationChangeFunc,!1)}size(t,e){var i;let n=t||this.settings.width,r=e||this.settings.height;null===t?(i=this.element.getBoundingClientRect()).width&&(t=Math.floor(i.width),this.container.style.width=t+"px"):Object(s.isNumber)(t)?this.container.style.width=t+"px":this.container.style.width=t,null===e?(i=i||this.element.getBoundingClientRect()).height&&(e=i.height,this.container.style.height=e+"px"):Object(s.isNumber)(e)?this.container.style.height=e+"px":this.container.style.height=e,Object(s.isNumber)(t)||(t=this.container.clientWidth),Object(s.isNumber)(e)||(e=this.container.clientHeight),this.containerStyles=window.getComputedStyle(this.container),this.containerPadding={left:parseFloat(this.containerStyles["padding-left"])||0,right:parseFloat(this.containerStyles["padding-right"])||0,top:parseFloat(this.containerStyles["padding-top"])||0,bottom:parseFloat(this.containerStyles["padding-bottom"])||0};let o=Object(s.windowBounds)(),a=window.getComputedStyle(document.body),h=parseFloat(a["padding-left"])||0,l=parseFloat(a["padding-right"])||0,c=parseFloat(a["padding-top"])||0,u=parseFloat(a["padding-bottom"])||0;return n||(t=o.width-h-l),(this.settings.fullsize&&!r||!r)&&(e=o.height-c-u),{width:t-this.containerPadding.left-this.containerPadding.right,height:e-this.containerPadding.top-this.containerPadding.bottom}}bounds(){let t;return"visible"!==this.container.style.overflow&&(t=this.container&&this.container.getBoundingClientRect()),t&&t.width&&t.height?t:Object(s.windowBounds)()}getSheet(){var t=document.createElement("style");return t.appendChild(document.createTextNode("")),document.head.appendChild(t),t.sheet}addStyleRules(t,e){var i="#"+this.id+" ",n="";this.sheet||(this.sheet=this.getSheet()),e.forEach((function(t){for(var e in t)t.hasOwnProperty(e)&&(n+=e+":"+t[e]+";")})),this.sheet.insertRule(i+t+" {"+n+"}",0)}axis(t){"horizontal"===t?(this.container.style.display="flex",this.container.style.flexDirection="row",this.container.style.flexWrap="nowrap"):this.container.style.display="block",this.settings.axis=t}direction(t){this.container&&(this.container.dir=t,this.container.style.direction=t),this.settings.fullsize&&(document.body.style.direction=t),this.settings.dir=t}overflow(t){this.container&&("scroll"===t&&"vertical"===this.settings.axis?(this.container.style["overflow-y"]=t,this.container.style["overflow-x"]="hidden"):"scroll"===t&&"horizontal"===this.settings.axis?(this.container.style["overflow-y"]="hidden",this.container.style["overflow-x"]=t):this.container.style.overflow=t),this.settings.overflow=t}destroy(){this.element&&(this.settings.hidden?this.wrapper:this.container,this.element.contains(this.container)&&this.element.removeChild(this.container),window.removeEventListener("resize",this.resizeFunc),window.removeEventListener("orientationChange",this.orientationChangeFunc))}};var d=class{constructor(t){this.container=t,this._views=[],this.length=0,this.hidden=!1}all(){return this._views}first(){return this._views[0]}last(){return this._views[this._views.length-1]}indexOf(t){return this._views.indexOf(t)}slice(){return this._views.slice.apply(this._views,arguments)}get(t){return this._views[t]}append(t){return this._views.push(t),this.container&&this.container.appendChild(t.element),this.length++,t}prepend(t){return this._views.unshift(t),this.container&&this.container.insertBefore(t.element,this.container.firstChild),this.length++,t}insert(t,e){return this._views.splice(e,0,t),this.container&&(e-1&&this._views.splice(e,1),this.destroy(t),this.length--}destroy(t){t.displayed&&t.destroy(),this.container&&this.container.removeChild(t.element),t=null}forEach(){return this._views.forEach.apply(this._views,arguments)}clear(){var t,e=this.length;if(this.length){for(var i=0;i1){if(t||0===e.index)return;if(n=e.next(),n&&!n.properties.includes("page-spread-left"))return i.call(this,n)}}display(t,e){var i=new s.defer,n=i.promise;(e===t.href||Object(s.isNumber)(e))&&(e=void 0);var r=this.views.find(t);if(r&&t&&"pre-paginated"!==this.layout.name){let t=r.offset();if("ltr"===this.settings.direction)this.scrollTo(t.left,t.top,!0);else{let e=r.width();this.scrollTo(t.left+e,t.top,!0)}if(e){let t=r.locationOf(e);this.moveTo(t)}return i.resolve(),n}this.clear();let o=!1;return"pre-paginated"===this.layout.name&&2===this.layout.divisor&&t.properties.includes("page-spread-right")&&(o=!0),this.add(t,o).then(function(t){if(e){let i=t.locationOf(e);this.moveTo(i)}}.bind(this),t=>{i.reject(t)}).then(function(){return this.handleNextPrePaginated(o,t,this.add)}.bind(this)).then(function(){this.views.show(),i.resolve()}.bind(this)),n}afterDisplayed(t){this.emit(f.c.MANAGERS.ADDED,t)}afterResized(t){this.emit(f.c.MANAGERS.RESIZE,t.section)}moveTo(t){var e=0,i=0;this.isPaginated?(e=Math.floor(t.left/this.layout.delta)*this.layout.delta)+this.layout.delta>this.container.scrollWidth&&(e=this.container.scrollWidth-this.layout.delta):i=t.top,this.scrollTo(e,i,!0)}add(t,e){var i=this.createView(t,e);return this.views.append(i),i.onDisplayed=this.afterDisplayed.bind(this),i.onResize=this.afterResized.bind(this),i.on(f.c.VIEWS.AXIS,t=>{this.updateAxis(t)}),i.on(f.c.VIEWS.WRITING_MODE,t=>{this.updateWritingMode(t)}),i.display(this.request)}append(t,e){var i=this.createView(t,e);return this.views.append(i),i.onDisplayed=this.afterDisplayed.bind(this),i.onResize=this.afterResized.bind(this),i.on(f.c.VIEWS.AXIS,t=>{this.updateAxis(t)}),i.on(f.c.VIEWS.WRITING_MODE,t=>{this.updateWritingMode(t)}),i.display(this.request)}prepend(t,e){var i=this.createView(t,e);return i.on(f.c.VIEWS.RESIZED,t=>{this.counter(t)}),this.views.prepend(i),i.onDisplayed=this.afterDisplayed.bind(this),i.onResize=this.afterResized.bind(this),i.on(f.c.VIEWS.AXIS,t=>{this.updateAxis(t)}),i.on(f.c.VIEWS.WRITING_MODE,t=>{this.updateWritingMode(t)}),i.display(this.request)}counter(t){"vertical"===this.settings.axis?this.scrollBy(0,t.heightDelta,!0):this.scrollBy(t.widthDelta,0,!0)}next(){var t;let e=this.settings.direction;if(this.views.length){if(!this.isPaginated||"horizontal"!==this.settings.axis||e&&"ltr"!==e)if(this.isPaginated&&"horizontal"===this.settings.axis&&"rtl"===e)this.scrollLeft=this.container.scrollLeft,"default"===this.settings.rtlScrollType?this.container.scrollLeft>0?this.scrollBy(this.layout.delta,0,!0):t=this.views.last().section.next():this.container.scrollLeft+-1*this.layout.delta>-1*this.container.scrollWidth?this.scrollBy(this.layout.delta,0,!0):t=this.views.last().section.next();else if(this.isPaginated&&"vertical"===this.settings.axis){this.scrollTop=this.container.scrollTop,this.container.scrollTop+this.container.offsetHeightt).then(function(){this.isPaginated||"horizontal"!==this.settings.axis||"rtl"!==this.settings.direction||"default"!==this.settings.rtlScrollType||this.scrollTo(this.container.scrollWidth,0,!0),this.views.show()}.bind(this))}}}prev(){var t;let e=this.settings.direction;if(this.views.length){if(!this.isPaginated||"horizontal"!==this.settings.axis||e&&"ltr"!==e)if(this.isPaginated&&"horizontal"===this.settings.axis&&"rtl"===e)this.scrollLeft=this.container.scrollLeft,"default"===this.settings.rtlScrollType?this.container.scrollLeft+this.container.offsetWidth0?this.scrollBy(0,-this.layout.height,!0):t=this.views.first().section.prev()}else t=this.views.first().section.prev();else this.scrollLeft=this.container.scrollLeft,this.container.scrollLeft>0?this.scrollBy(-this.layout.delta,0,!0):t=this.views.first().section.prev();if(t){this.clear();let e=!1;return"pre-paginated"===this.layout.name&&2===this.layout.divisor&&"object"!=typeof t.prev()&&(e=!0),this.prepend(t,e).then(function(){var e;if("pre-paginated"===this.layout.name&&this.layout.divisor>1&&(e=t.prev()))return this.prepend(e)}.bind(this),t=>t).then(function(){this.isPaginated&&"horizontal"===this.settings.axis&&("rtl"===this.settings.direction?"default"===this.settings.rtlScrollType?this.scrollTo(0,0,!0):this.scrollTo(-1*this.container.scrollWidth+this.layout.delta,0,!0):this.scrollTo(this.container.scrollWidth-this.layout.delta,0,!0)),this.views.show()}.bind(this))}}}current(){var t=this.visible();return t.length?t[t.length-1]:null}clear(){this.views&&(this.views.hide(),this.scrollTo(0,0,!0),this.views.clear())}currentLocation(){return this.isPaginated&&"horizontal"===this.settings.axis?this.location=this.paginatedLocation():this.location=this.scrolledLocation(),this.location}scrolledLocation(){let t=this.visible(),e=this.container.getBoundingClientRect(),i=e.height{let o,a,h,l,{index:c,href:u}=t.section,d=t.position(),f=t.width(),p=t.height();r?(o=s+e.top-d.top+0,a=o+i-0,l=this.layout.count(p,i).pages,h=i):(o=s+e.left-d.left+0,a=o+n-0,l=this.layout.count(f,n).pages,h=n);let g=Math.ceil(o/h),v=[],m=Math.ceil(a/h);if("rtl"===this.settings.direction&&!r){let t=g;g=l-m,m=l-t}v=[];for(var y=g;y<=m;y++){let t=y+1;v.push(t)}return{index:c,href:u,pages:v,totalPages:l,mapping:this.mapping.page(t.contents,t.section.cfiBase,o,a)}})}paginatedLocation(){let t=this.visible(),e=this.container.getBoundingClientRect(),i=0,n=0;return this.settings.fullsize&&(i=window.scrollX),t.map(t=>{let r,s,o,a,{index:h,href:l}=t.section,c=t.position(),u=t.width();"rtl"===this.settings.direction?(r=e.right-i,a=Math.min(Math.abs(r-c.left),this.layout.width)-n,o=c.width-(c.right-r)-n,s=o-a):(r=e.left+i,a=Math.min(c.right-r,this.layout.width)-n,s=r-c.left+n,o=s+a),n+=a;let d=this.mapping.page(t.contents,t.section.cfiBase,s,o),f=this.layout.count(u).pages,p=Math.floor(s/this.layout.pageWidth),g=[],v=Math.floor(o/this.layout.pageWidth);if(p<0&&(p=0,v+=1),"rtl"===this.settings.direction){let t=p;p=f-v,v=f-t}for(var m=p+1;m<=v;m++){let t=m;g.push(t)}return{index:h,href:l,pages:g,totalPages:f,mapping:d}})}isVisible(t,e,i,n){var r=t.position(),s=n||this.bounds();return"horizontal"===this.settings.axis&&r.right>s.left-e&&r.lefts.top-e&&r.top0&&"pre-paginated"===this.layout.name&&this.display(this.views.first().section)}updateLayout(){this.stage&&(this._stageSize=this.stage.size(),this.isPaginated?(this.layout.calculate(this._stageSize.width,this._stageSize.height,this.settings.gap),this.settings.offset=this.layout.delta/this.layout.divisor):this.layout.calculate(this._stageSize.width,this._stageSize.height),this.viewSettings.width=this.layout.width,this.viewSettings.height=this.layout.height,this.setLayout(this.layout))}setLayout(t){this.viewSettings.layout=t,this.mapping=new a.a(t.props,this.settings.direction,this.settings.axis),this.views&&this.views.forEach((function(e){e&&e.setLayout(t)}))}updateWritingMode(t){this.writingMode=t}updateAxis(t,e){(e||t!==this.settings.axis)&&(this.settings.axis=t,this.stage&&this.stage.axis(t),this.viewSettings.axis=t,this.mapping&&(this.mapping=new a.a(this.layout.props,this.settings.direction,this.settings.axis)),this.layout&&("vertical"===t?this.layout.spread("none"):this.layout.spread(this.layout.settings.spread)))}updateFlow(t,e="auto"){let i="paginated"===t||"auto"===t;this.isPaginated=i,"scrolled-doc"===t||"scrolled-continuous"===t||"scrolled"===t?this.updateAxis("vertical"):this.updateAxis("horizontal"),this.viewSettings.flow=t,this.settings.overflow?this.overflow=this.settings.overflow:this.overflow=i?"hidden":e,this.stage&&this.stage.overflow(this.overflow),this.updateLayout()}getContents(){var t=[];return this.views?(this.views.forEach((function(e){const i=e&&e.contents;i&&t.push(i)})),t):t}direction(t="ltr"){this.settings.direction=t,this.stage&&this.stage.direction(t),this.viewSettings.direction=t,this.updateLayout()}isRendered(){return this.rendered}}r()(p.prototype);e.a=p},function(t,e,i){"use strict";var n=i(2),r=i(0);e.a=class{constructor(t,e,i,n=!1){this.layout=t,this.horizontal="horizontal"===i,this.direction=e||"ltr",this._dev=n}section(t){var e=this.findRanges(t);return this.rangeListToCfiList(t.section.cfiBase,e)}page(t,e,i,r){var s,o=!(!t||!t.document)&&t.document.body;if(o){if(s=this.rangePairToCfiPair(e,{start:this.findStart(o,i,r),end:this.findEnd(o,i,r)}),!0===this._dev){let e=t.document,i=new n.a(s.start).toRange(e),r=new n.a(s.end).toRange(e),o=e.defaultView.getSelection(),a=e.createRange();o.removeAllRanges(),a.setStart(i.startContainer,i.startOffset),a.setEnd(r.endContainer,r.endOffset),o.addRange(a)}return s}}walk(t,e){if(!t||t.nodeType!==Node.TEXT_NODE){var i=function(t){return t.data.trim().length>0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT},n=i;n.acceptNode=i;for(var r,s,o=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,n,!1);(r=o.nextNode())&&!(s=e(r)););return s}}findRanges(t){for(var e,i,n=[],r=t.contents.scrollWidth(),s=Math.ceil(r/this.layout.spreadWidth)*this.layout.divisor,o=this.layout.columnWidth,a=this.layout.gap,h=0;h{var n,s,h,l,c;if(c=Object(r.nodeBounds)(t),this.horizontal&&"ltr"===this.direction){if(n=this.horizontal?c.left:c.top,s=this.horizontal?c.right:c.bottom,n>=e&&n<=i)return t;if(s>e)return t;a=t,o.push(t)}else if(this.horizontal&&"rtl"===this.direction){if(n=c.left,(s=c.right)<=i&&s>=e)return t;if(n=e&&h<=i)return t;if(l>e)return t;a=t,o.push(t)}}))return this.findTextStartRange(s,e,i);return this.findTextStartRange(a,e,i)}findEnd(t,e,i){for(var n,s,o=[t],a=t;o.length;)if(n=o.shift(),s=this.walk(n,t=>{var n,s,h,l,c;if(c=Object(r.nodeBounds)(t),this.horizontal&&"ltr"===this.direction){if(n=Math.round(c.left),s=Math.round(c.right),n>i&&a)return a;if(s>i)return t;a=t,o.push(t)}else if(this.horizontal&&"rtl"===this.direction){if(n=Math.round(this.horizontal?c.left:c.top),(s=Math.round(this.horizontal?c.right:c.bottom))i&&a)return a;if(l>i)return t;a=t,o.push(t)}}))return this.findTextEndRange(s,e,i);return this.findTextEndRange(a,e,i)}findTextStartRange(t,e,i){for(var n,r,s=this.splitTextNodeIntoRanges(t),o=0;o=e)return n}else if(this.horizontal&&"rtl"===this.direction){if(r.right<=i)return n}else if(r.top>=e)return n;return s[0]}findTextEndRange(t,e,i){for(var n,r,s,o,a,h,l,c=this.splitTextNodeIntoRanges(t),u=0;ui&&n)return n;if(a>i)return r}else if(this.horizontal&&"rtl"===this.direction){if(o=s.left,(a=s.right)i&&n)return n;if(l>i)return r}n=r}return c[c.length-1]}splitTextNodeIntoRanges(t,e){var i,n=[],r=(t.textContent||"").trim(),s=t.ownerDocument,o=e||" ",a=r.indexOf(o);if(-1===a||t.nodeType!=Node.TEXT_NODE)return(i=s.createRange()).selectNodeContents(t),[i];for((i=s.createRange()).setStart(t,0),i.setEnd(t,a),n.push(i),i=!1;-1!=a;)(a=r.indexOf(o,a+1))>0&&(i&&(i.setEnd(t,a),n.push(i)),(i=s.createRange()).setStart(t,a+1));return i&&(i.setEnd(t,r.length),n.push(i)),n}rangePairToCfiPair(t,e){var i=e.start,r=e.end;return i.collapse(!0),r.collapse(!1),{start:new n.a(i,t).toString(),end:new n.a(r,t).toString()}}rangeListToCfiList(t,e){for(var i,n=[],r=0;r]*>)/g,g=/\$([$&'`]|\d\d?)/g;n("replace",2,(function(t,e,i,n){var v=n.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,m=n.REPLACE_KEEPS_$0,y=v?"$":"$0";return[function(i,n){var r=h(this),s=null==i?void 0:i[t];return void 0!==s?s.call(i,r,n):e.call(String(r),i,n)},function(t,n){if(!v&&m||"string"==typeof n&&-1===n.indexOf(y)){var s=i(e,t,this,n);if(s.done)return s.value}var h=r(t),f=String(this),p="function"==typeof n;p||(n=String(n));var g=h.global;if(g){var w=h.unicode;h.lastIndex=0}for(var x=[];;){var E=c(h,f);if(null===E)break;if(x.push(E),!g)break;""===String(E[0])&&(h.lastIndex=l(f,o(h.lastIndex),w))}for(var S,_="",O=0,C=0;C=O&&(_+=f.slice(O,k)+N,O=k+T.length)}return _+f.slice(O)}];function b(t,i,n,r,o,a){var h=n+t.length,l=r.length,c=g;return void 0!==o&&(o=s(o),c=p),e.call(a,c,(function(e,s){var a;switch(s.charAt(0)){case"$":return"$";case"&":return t;case"`":return i.slice(0,n);case"'":return i.slice(h);case"<":a=o[s.slice(1,-1)];break;default:var c=+s;if(0===c)return e;if(c>l){var u=f(c/10);return 0===u?e:u<=l?void 0===r[u-1]?s.charAt(1):r[u-1]+s.charAt(1):e}a=r[c-1]}return void 0===a?"":a}))}}))},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,i){var n,r,s,o=i(89),a=i(7),h=i(17),l=i(15),c=i(10),u=i(43),d=i(44),f=a.WeakMap;if(o){var p=new f,g=p.get,v=p.has,m=p.set;n=function(t,e){return m.call(p,t,e),e},r=function(t){return g.call(p,t)||{}},s=function(t){return v.call(p,t)}}else{var y=u("state");d[y]=!0,n=function(t,e){return l(t,y,e),e},r=function(t){return c(t,y)?t[y]:{}},s=function(t){return c(t,y)}}t.exports={set:n,get:r,has:s,enforce:function(t){return s(t)?r(t):n(t,{})},getterFor:function(t){return function(e){var i;if(!h(e)||(i=r(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return i}}}},function(t,e){t.exports={}},function(t,e,i){"use strict";var n=i(3),r=i.n(n),s=i(0),o=i(2),a=i(23),h=i(11),l=i(1);const c="undefined"!=typeof navigator,u=c&&/Chrome/.test(navigator.userAgent),d=c&&!u&&/AppleWebKit/.test(navigator.userAgent);class f{constructor(t,e,i,n){this.epubcfi=new o.a,this.document=t,this.documentElement=this.document.documentElement,this.content=e||this.document.body,this.window=this.document.defaultView,this._size={width:0,height:0},this.sectionIndex=n||0,this.cfiBase=i||"",this.epubReadingSystem("epub.js",l.b),this.called=0,this.active=!0,this.listeners()}static get listenedEvents(){return l.a}width(t){var e=this.content;return t&&Object(s.isNumber)(t)&&(t+="px"),t&&(e.style.width=t),parseInt(this.window.getComputedStyle(e).width)}height(t){var e=this.content;return t&&Object(s.isNumber)(t)&&(t+="px"),t&&(e.style.height=t),parseInt(this.window.getComputedStyle(e).height)}contentWidth(t){var e=this.content||this.document.body;return t&&Object(s.isNumber)(t)&&(t+="px"),t&&(e.style.width=t),parseInt(this.window.getComputedStyle(e).width)}contentHeight(t){var e=this.content||this.document.body;return t&&Object(s.isNumber)(t)&&(t+="px"),t&&(e.style.height=t),parseInt(this.window.getComputedStyle(e).height)}textWidth(){let t,e,i=this.document.createRange(),n=this.content||this.document.body,r=Object(s.borders)(n);return i.selectNodeContents(n),t=i.getBoundingClientRect(),e=t.width,r&&r.width&&(e+=r.width),Math.round(e)}textHeight(){let t,e,i=this.document.createRange(),n=this.content||this.document.body;return i.selectNodeContents(n),t=i.getBoundingClientRect(),e=t.bottom,Math.round(e)}scrollWidth(){return this.documentElement.scrollWidth}scrollHeight(){return this.documentElement.scrollHeight}overflow(t){return t&&(this.documentElement.style.overflow=t),this.window.getComputedStyle(this.documentElement).overflow}overflowX(t){return t&&(this.documentElement.style.overflowX=t),this.window.getComputedStyle(this.documentElement).overflowX}overflowY(t){return t&&(this.documentElement.style.overflowY=t),this.window.getComputedStyle(this.documentElement).overflowY}css(t,e,i){var n=this.content||this.document.body;return e?n.style.setProperty(t,e,i?"important":""):n.style.removeProperty(t),this.window.getComputedStyle(n)[t]}viewport(t){var e,i=this.document.querySelector("meta[name='viewport']"),n={width:void 0,height:void 0,scale:void 0,minimum:void 0,maximum:void 0,scalable:void 0},r=[];if(i&&i.hasAttribute("content")){let t=i.getAttribute("content"),e=t.match(/width\s*=\s*([^,]*)/),r=t.match(/height\s*=\s*([^,]*)/),s=t.match(/initial-scale\s*=\s*([^,]*)/),o=t.match(/minimum-scale\s*=\s*([^,]*)/),a=t.match(/maximum-scale\s*=\s*([^,]*)/),h=t.match(/user-scalable\s*=\s*([^,]*)/);e&&e.length&&void 0!==e[1]&&(n.width=e[1]),r&&r.length&&void 0!==r[1]&&(n.height=r[1]),s&&s.length&&void 0!==s[1]&&(n.scale=s[1]),o&&o.length&&void 0!==o[1]&&(n.minimum=o[1]),a&&a.length&&void 0!==a[1]&&(n.maximum=a[1]),h&&h.length&&void 0!==h[1]&&(n.scalable=h[1])}return e=Object(s.defaults)(t||{},n),t&&(e.width&&r.push("width="+e.width),e.height&&r.push("height="+e.height),e.scale&&r.push("initial-scale="+e.scale),"no"===e.scalable?(r.push("minimum-scale="+e.scale),r.push("maximum-scale="+e.scale),r.push("user-scalable="+e.scalable)):(e.scalable&&r.push("user-scalable="+e.scalable),e.minimum&&r.push("minimum-scale="+e.minimum),e.maximum&&r.push("minimum-scale="+e.maximum)),i||((i=this.document.createElement("meta")).setAttribute("name","viewport"),this.document.querySelector("head").appendChild(i)),i.setAttribute("content",r.join(", ")),this.window.scrollTo(0,0)),e}expand(){this.emit(l.c.CONTENTS.EXPAND)}listeners(){this.imageLoadListeners(),this.mediaQueryListeners(),this.addEventListeners(),this.addSelectionListeners(),"undefined"==typeof ResizeObserver?(this.resizeListeners(),this.visibilityListeners()):this.resizeObservers(),this.linksHandler()}removeListeners(){this.removeEventListeners(),this.removeSelectionListeners(),this.observer&&this.observer.disconnect(),clearTimeout(this.expanding)}resizeCheck(){let t=this.textWidth(),e=this.textHeight();t==this._size.width&&e==this._size.height||(this._size={width:t,height:e},this.onResize&&this.onResize(this._size),this.emit(l.c.CONTENTS.RESIZE,this._size))}resizeListeners(){clearTimeout(this.expanding),requestAnimationFrame(this.resizeCheck.bind(this)),this.expanding=setTimeout(this.resizeListeners.bind(this),350)}visibilityListeners(){document.addEventListener("visibilitychange",()=>{"visible"===document.visibilityState&&!1===this.active?(this.active=!0,this.resizeListeners()):(this.active=!1,clearTimeout(this.expanding))})}transitionListeners(){let t=this.content;t.style.transitionProperty="font, font-size, font-size-adjust, font-stretch, font-variation-settings, font-weight, width, height",t.style.transitionDuration="0.001ms",t.style.transitionTimingFunction="linear",t.style.transitionDelay="0",this._resizeCheck=this.resizeCheck.bind(this),this.document.addEventListener("transitionend",this._resizeCheck)}mediaQueryListeners(){for(var t=this.document.styleSheets,e=function(t){t.matches&&!this._expanding&&setTimeout(this.expand.bind(this),1)}.bind(this),i=0;i{requestAnimationFrame(this.resizeCheck.bind(this))}),this.observer.observe(this.document.documentElement)}mutationObservers(){this.observer=new MutationObserver(t=>{this.resizeCheck()});this.observer.observe(this.document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})}imageLoadListeners(){for(var t,e=this.document.querySelectorAll("img"),i=0;i0?(e.setStart(t,r.startOffset-2),e.setEnd(t,r.startOffset),i=e.getBoundingClientRect()):i=t.parentNode.getBoundingClientRect()}catch(t){console.error(t,t.stack)}}else i=r.getBoundingClientRect()}}else if("string"==typeof t&&t.indexOf("#")>-1){let e=t.substring(t.indexOf("#")+1),n=this.document.getElementById(e);if(n)if(d){let t=new Range;t.selectNode(n),i=t.getBoundingClientRect()}else i=n.getBoundingClientRect()}return i&&(n.left=i.left,n.top=i.top),n}addStylesheet(t){return new Promise(function(e,i){var n,r=!1;this.document?(n=this.document.querySelector("link[href='"+t+"']"))?e(!0):((n=this.document.createElement("link")).type="text/css",n.rel="stylesheet",n.href=t,n.onload=n.onreadystatechange=function(){r||this.readyState&&"complete"!=this.readyState||(r=!0,setTimeout(()=>{e(!0)},1))},this.document.head.appendChild(n)):e(!1)}.bind(this))}_getStylesheetNode(t){var e;return t="epubjs-inserted-css-"+(t||""),!!this.document&&((e=this.document.getElementById(t))||((e=this.document.createElement("style")).id=t,this.document.head.appendChild(e)),e)}addStylesheetCss(t,e){return!(!this.document||!t)&&(this._getStylesheetNode(e).innerHTML=t,!0)}addStylesheetRules(t,e){var i;if(this.document&&t&&0!==t.length)if(i=this._getStylesheetNode(e).sheet,"[object Array]"===Object.prototype.toString.call(t))for(var n=0,r=t.length;n{const n=t[e];if(Array.isArray(n))n.forEach(t=>{const n=Object.keys(t).map(e=>`${e}:${t[e]}`).join(";");i.insertRule(`${e}{${n}}`,i.cssRules.length)});else{const t=Object.keys(n).map(t=>`${t}:${n[t]}`).join(";");i.insertRule(`${e}{${t}}`,i.cssRules.length)}})}}addScript(t){return new Promise(function(e,i){var n,r=!1;this.document?((n=this.document.createElement("script")).type="text/javascript",n.async=!0,n.src=t,n.onload=n.onreadystatechange=function(){r||this.readyState&&"complete"!=this.readyState||(r=!0,setTimeout((function(){e(!0)}),1))},this.document.head.appendChild(n)):e(!1)}.bind(this))}addClass(t){var e;this.document&&(e=this.content||this.document.body)&&e.classList.add(t)}removeClass(t){var e;this.document&&(e=this.content||this.document.body)&&e.classList.remove(t)}addEventListeners(){this.document&&(this._triggerEvent=this.triggerEvent.bind(this),l.a.forEach((function(t){this.document.addEventListener(t,this._triggerEvent,{passive:!0})}),this))}removeEventListeners(){this.document&&(l.a.forEach((function(t){this.document.removeEventListener(t,this._triggerEvent,{passive:!0})}),this),this._triggerEvent=void 0)}triggerEvent(t){this.emit(t.type,t)}addSelectionListeners(){this.document&&(this._onSelectionChange=this.onSelectionChange.bind(this),this.document.addEventListener("selectionchange",this._onSelectionChange,{passive:!0}))}removeSelectionListeners(){this.document&&(this.document.removeEventListener("selectionchange",this._onSelectionChange,{passive:!0}),this._onSelectionChange=void 0)}onSelectionChange(t){this.selectionEndTimeout&&clearTimeout(this.selectionEndTimeout),this.selectionEndTimeout=setTimeout(function(){var t=this.window.getSelection();this.triggerSelectedEvent(t)}.bind(this),250)}triggerSelectedEvent(t){var e,i;t&&t.rangeCount>0&&((e=t.getRangeAt(0)).collapsed||(i=new o.a(e,this.cfiBase).toString(),this.emit(l.c.CONTENTS.SELECTED,i),this.emit(l.c.CONTENTS.SELECTED_RANGE,e)))}range(t,e){return new o.a(t).toRange(this.document,e)}cfiFromRange(t,e){return new o.a(t,this.cfiBase,e).toString()}cfiFromNode(t,e){return new o.a(t,this.cfiBase,e).toString()}map(t){return new a.a(t).section()}size(t,e){var i={scale:1,scalable:"no"};this.layoutStyle("scrolling"),t>=0&&(this.width(t),i.width=t,this.css("padding","0 "+t/12+"px")),e>=0&&(this.height(e),i.height=e),this.css("margin","0"),this.css("box-sizing","border-box"),this.viewport(i)}columns(t,e,i,n,r){let o=Object(s.prefixed)("column-axis"),a=Object(s.prefixed)("column-gap"),h=Object(s.prefixed)("column-width"),l=Object(s.prefixed)("column-fill"),c=0===this.writingMode().indexOf("vertical")?"vertical":"horizontal";this.layoutStyle("paginated"),"rtl"===r&&"horizontal"===c&&this.direction(r),this.width(t),this.height(e),this.viewport({width:t,height:e,scale:1,scalable:"no"}),this.css("overflow-y","hidden"),this.css("margin","0",!0),"vertical"===c?(this.css("padding-top",n/2+"px",!0),this.css("padding-bottom",n/2+"px",!0),this.css("padding-left","20px"),this.css("padding-right","20px"),this.css(o,"vertical")):(this.css("padding-top","20px"),this.css("padding-bottom","20px"),this.css("padding-left",n/2+"px",!0),this.css("padding-right",n/2+"px",!0),this.css(o,"horizontal")),this.css("box-sizing","border-box"),this.css("max-width","inherit"),this.css(l,"auto"),this.css(a,n+"px"),this.css(h,i+"px"),this.css("-webkit-line-box-contain","block glyphs replaced")}scaler(t,e,i){var n="scale("+t+")",r="";this.css("transform-origin","top left"),(e>=0||i>=0)&&(r=" translate("+(e||0)+"px, "+(i||0)+"px )"),this.css("transform",n+r)}fit(t,e,i){var n=this.viewport(),r=parseInt(n.width),s=parseInt(n.height),o=t/r,a=e/s,h=o{this.emit(l.c.CONTENTS.LINK_CLICKED,t)})}writingMode(t){let e=Object(s.prefixed)("writing-mode");return t&&this.documentElement&&(this.documentElement.style[e]=t),this.window.getComputedStyle(this.documentElement)[e]||""}layoutStyle(t){return t&&(this._layoutStyle=t,navigator.epubReadingSystem.layoutStyle=this._layoutStyle),this._layoutStyle||"paginated"}epubReadingSystem(t,e){return navigator.epubReadingSystem={name:t,version:e,layoutStyle:this.layoutStyle(),hasFeature:function(t){switch(t){case"dom-manipulation":case"layout-changes":case"touch-events":case"mouse-events":case"keyboard-events":return!0;case"spine-scripting":default:return!1}}},navigator.epubReadingSystem}destroy(){this.removeListeners()}}r()(f.prototype),e.a=f},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Underline=e.Highlight=e.Mark=e.Pane=void 0;var n=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:document.body;l(this,t),this.target=e,this.element=r.default.createElement("svg"),this.marks=[],this.element.style.position="absolute",this.element.setAttribute("pointer-events","none"),s.default.proxyMouse(this.target,this.marks),this.container=i,this.container.appendChild(this.element),this.render()}return n(t,[{key:"addMark",value:function(t){var e=r.default.createElement("g");return this.element.appendChild(e),t.bind(e,this.container),this.marks.push(t),t.render(),t}},{key:"removeMark",value:function(t){var e=this.marks.indexOf(t);if(-1!==e){var i=t.unbind();this.element.removeChild(i),this.marks.splice(e,1)}}},{key:"render",value:function(){var t,e,i,n;!function(t,e){t.style.setProperty("top",e.top+"px","important"),t.style.setProperty("left",e.left+"px","important"),t.style.setProperty("height",e.height+"px","important"),t.style.setProperty("width",e.width+"px","important")}(this.element,(t=this.target,e=this.container,i=e.getBoundingClientRect(),n=t.getBoundingClientRect(),{top:n.top-i.top,left:n.left-i.left,height:t.scrollHeight,width:t.scrollWidth}));var r=!0,s=!1,o=void 0;try{for(var a,h=this.marks[Symbol.iterator]();!(r=(a=h.next()).done);r=!0){a.value.render()}}catch(t){s=!0,o=t}finally{try{!r&&h.return&&h.return()}finally{if(s)throw o}}}}]),t}();var c=e.Mark=function(){function t(){l(this,t),this.element=null}return n(t,[{key:"bind",value:function(t,e){this.element=t,this.container=e}},{key:"unbind",value:function(){var t=this.element;return this.element=null,t}},{key:"render",value:function(){}},{key:"dispatchEvent",value:function(t){this.element&&this.element.dispatchEvent(t)}},{key:"getBoundingClientRect",value:function(){return this.element.getBoundingClientRect()}},{key:"getClientRects",value:function(){for(var t=[],e=this.element.firstChild;e;)t.push(e.getBoundingClientRect()),e=e.nextSibling;return t}},{key:"filteredRanges",value:function(){var t=Array.from(this.range.getClientRects());return t.filter((function(e){for(var i=0;i=n.left&&r.top>=n.top&&r.bottom<=n.bottom)return!1}var n,r;return!0}))}}]),t}(),u=e.Highlight=function(t){function e(t,i,n,r){l(this,e);var s=a(this,(e.__proto__||Object.getPrototypeOf(e)).call(this));return s.range=t,s.className=i,s.data=n||{},s.attributes=r||{},s}return h(e,t),n(e,[{key:"bind",value:function(t,i){for(var n in function t(e,i,n){null===e&&(e=Function.prototype);var r=Object.getOwnPropertyDescriptor(e,i);if(void 0===r){var s=Object.getPrototypeOf(e);return null===s?void 0:t(s,i,n)}if("value"in r)return r.value;var o=r.get;return void 0!==o?o.call(n):void 0}(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"bind",this).call(this,t,i),this.data)this.data.hasOwnProperty(n)&&(this.element.dataset[n]=this.data[n]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&this.element.setAttribute(n,this.attributes[n]);this.className&&this.element.classList.add(this.className)}},{key:"render",value:function(){for(;this.element.firstChild;)this.element.removeChild(this.element.firstChild);for(var t=this.element.ownerDocument.createDocumentFragment(),e=this.filteredRanges(),i=this.element.getBoundingClientRect(),n=this.container.getBoundingClientRect(),s=0,o=e.length;s0?n:i)(t)}},function(t,e,i){var n=i(33);t.exports=function(t){return Object(n(t))}},function(t,e,i){var n=i(18).f,r=i(10),s=i(8)("toStringTag");t.exports=function(t,e,i){t&&!r(t=i?t:t.prototype,s)&&n(t,s,{configurable:!0,value:e})}},function(e,i){e.exports=t},function(t,e,i){"use strict";var n=i(3),r=i.n(n),s=i(0),o=i(6),a=i(2),h=i(21),l=i(1);class c{constructor(t){this.settings=t,this.name=t.layout||"reflowable",this._spread="none"!==t.spread,this._minSpreadWidth=t.minSpreadWidth||800,this._evenSpreads=t.evenSpreads||!1,"scrolled"===t.flow||"scrolled-continuous"===t.flow||"scrolled-doc"===t.flow?this._flow="scrolled":this._flow="paginated",this.width=0,this.height=0,this.spreadWidth=0,this.delta=0,this.columnWidth=0,this.gap=0,this.divisor=1,this.props={name:this.name,spread:this._spread,flow:this._flow,width:0,height:0,spreadWidth:0,delta:0,columnWidth:0,gap:0,divisor:1}}flow(t){return void 0!==t&&(this._flow="scrolled"===t||"scrolled-continuous"===t||"scrolled-doc"===t?"scrolled":"paginated",this.update({flow:this._flow})),this._flow}spread(t,e){return t&&(this._spread="none"!==t,this.update({spread:this._spread})),e>=0&&(this._minSpreadWidth=e),this._spread}calculate(t,e,i){var n,r,s,o,a=1,h=i||0,l=t,c=e,u=Math.floor(l/12);a=this._spread&&l>=this._minSpreadWidth?2:1,"reflowable"!==this.name||"paginated"!==this._flow||i>=0||(h=u%2==0?u:u-1),"pre-paginated"===this.name&&(h=0),a>1?s=(n=l/a-h)+h:(n=l,s=l),"pre-paginated"===this.name&&a>1&&(l=n),r=n*a+h,o=l,this.width=l,this.height=c,this.spreadWidth=r,this.pageWidth=s,this.delta=o,this.columnWidth=n,this.gap=h,this.divisor=a,this.update({width:l,height:c,spreadWidth:r,pageWidth:s,delta:o,columnWidth:n,gap:h,divisor:a})}format(t,e,i){return"pre-paginated"===this.name?t.fit(this.columnWidth,this.height,e):"paginated"===this._flow?t.columns(this.width,this.height,this.columnWidth,this.gap,this.settings.direction):i&&"horizontal"===i?t.size(null,this.height):t.size(this.width,null)}count(t,e){let i,n;return"pre-paginated"===this.name?(i=1,n=1):"paginated"===this._flow?(e=e||this.delta,i=Math.ceil(t/e),n=i*this.divisor):(e=e||this.height,i=Math.ceil(t/e),n=i),{spreads:i,pages:n}}update(t){if(Object.keys(t).forEach(e=>{this.props[e]===t[e]&&delete t[e]}),Object.keys(t).length>0){let e=Object(s.extend)(this.props,t);this.emit(l.c.LAYOUT.UPDATED,e,t)}}}r()(c.prototype);var u=c,d=i(5);var f=class{constructor(t){this.rendition=t,this._themes={default:{rules:{},url:"",serialized:""}},this._overrides={},this._current="default",this._injected=[],this.rendition.hooks.content.register(this.inject.bind(this)),this.rendition.hooks.content.register(this.overrides.bind(this))}register(){if(0!==arguments.length)return 1===arguments.length&&"object"==typeof arguments[0]?this.registerThemes(arguments[0]):1===arguments.length&&"string"==typeof arguments[0]?this.default(arguments[0]):2===arguments.length&&"string"==typeof arguments[1]?this.registerUrl(arguments[0],arguments[1]):2===arguments.length&&"object"==typeof arguments[1]?this.registerRules(arguments[0],arguments[1]):void 0}default(t){if(t)return"string"==typeof t?this.registerUrl("default",t):"object"==typeof t?this.registerRules("default",t):void 0}registerThemes(t){for(var e in t)t.hasOwnProperty(e)&&("string"==typeof t[e]?this.registerUrl(e,t[e]):this.registerRules(e,t[e]))}registerCss(t,e){this._themes[t]={serialized:e},(this._injected[t]||"default"==t)&&this.update(t)}registerUrl(t,e){var i=new d.a(e);this._themes[t]={url:i.toString()},(this._injected[t]||"default"==t)&&this.update(t)}registerRules(t,e){this._themes[t]={rules:e},(this._injected[t]||"default"==t)&&this.update(t)}select(t){var e=this._current;this._current=t,this.update(t),this.rendition.getContents().forEach(i=>{i.removeClass(e),i.addClass(t)})}update(t){this.rendition.getContents().forEach(e=>{this.add(t,e)})}inject(t){var e,i=[],n=this._themes;for(var r in n)!n.hasOwnProperty(r)||r!==this._current&&"default"!==r||(((e=n[r]).rules&&Object.keys(e.rules).length>0||e.url&&-1===i.indexOf(e.url))&&this.add(r,t),this._injected.push(r));"default"!=this._current&&t.addClass(this._current)}add(t,e){var i=this._themes[t];i&&e&&(i.url?e.addStylesheet(i.url):i.serialized?(e.addStylesheetCss(i.serialized,t),i.injected=!0):i.rules&&(e.addStylesheetRules(i.rules,t),i.injected=!0))}override(t,e,i){var n=this.rendition.getContents();this._overrides[t]={value:e,priority:!0===i},n.forEach(e=>{e.css(t,this._overrides[t].value,this._overrides[t].priority)})}removeOverride(t){var e=this.rendition.getContents();delete this._overrides[t],e.forEach(e=>{e.css(t)})}overrides(t){var e=this._overrides;for(var i in e)e.hasOwnProperty(i)&&t.css(i,e[i].value,e[i].priority)}fontSize(t){this.override("font-size",t)}font(t){this.override("font-family",t,!0)}destroy(){this.rendition=void 0,this._themes=void 0,this._overrides=void 0,this._current=void 0,this._injected=void 0}};i(28);class p{constructor({type:t,cfiRange:e,data:i,sectionIndex:n,cb:r,className:s,styles:o}){this.type=t,this.cfiRange=e,this.data=i,this.sectionIndex=n,this.mark=void 0,this.cb=r,this.className=s,this.styles=o}update(t){this.data=t}attach(t){let e,{cfiRange:i,data:n,type:r,mark:s,cb:o,className:a,styles:h}=this;return"highlight"===r?e=t.highlight(i,n,o,a,h):"underline"===r?e=t.underline(i,n,o,a,h):"mark"===r&&(e=t.mark(i,n,o)),this.mark=e,this.emit(l.c.ANNOTATION.ATTACH,e),e}detach(t){let e,{cfiRange:i,type:n}=this;return t&&("highlight"===n?e=t.unhighlight(i):"underline"===n?e=t.ununderline(i):"mark"===n&&(e=t.unmark(i))),this.mark=void 0,this.emit(l.c.ANNOTATION.DETACH,e),e}text(){}}r()(p.prototype);var g=class{constructor(t){this.rendition=t,this.highlights=[],this.underlines=[],this.marks=[],this._annotations={},this._annotationsBySectionIndex={},this.rendition.hooks.render.register(this.inject.bind(this)),this.rendition.hooks.unloaded.register(this.clear.bind(this))}add(t,e,i,n,r,s){let o=encodeURI(e+t),h=new a.a(e).spinePos,l=new p({type:t,cfiRange:e,data:i,sectionIndex:h,cb:n,className:r,styles:s});return this._annotations[o]=l,h in this._annotationsBySectionIndex?this._annotationsBySectionIndex[h].push(o):this._annotationsBySectionIndex[h]=[o],this.rendition.views().forEach(t=>{l.sectionIndex===t.index&&l.attach(t)}),l}remove(t,e){let i=encodeURI(t+e);if(i in this._annotations){let t=this._annotations[i];if(e&&t.type!==e)return;this.rendition.views().forEach(e=>{this._removeFromAnnotationBySectionIndex(t.sectionIndex,i),t.sectionIndex===e.index&&t.detach(e)}),delete this._annotations[i]}}_removeFromAnnotationBySectionIndex(t,e){this._annotationsBySectionIndex[t]=this._annotationsAt(t).filter(t=>t!==e)}_annotationsAt(t){return this._annotationsBySectionIndex[t]}highlight(t,e,i,n,r){return this.add("highlight",t,e,i,n,r)}underline(t,e,i,n,r){return this.add("underline",t,e,i,n,r)}mark(t,e,i){return this.add("mark",t,e,i)}each(){return this._annotations.forEach.apply(this._annotations,arguments)}inject(t){let e=t.index;if(e in this._annotationsBySectionIndex){this._annotationsBySectionIndex[e].forEach(e=>{this._annotations[e].attach(t)})}}clear(t){let e=t.index;if(e in this._annotationsBySectionIndex){this._annotationsBySectionIndex[e].forEach(e=>{this._annotations[e].detach(t)})}}show(){}hide(){}},v=i(54),m=i(22),y=i(56);class b{constructor(t,e){this.settings=Object(s.extend)(this.settings||{},{width:null,height:null,ignoreClass:"",manager:"default",view:"iframe",flow:null,layout:null,spread:null,minSpreadWidth:800,stylesheet:null,resizeOnOrientationChange:!0,script:null,snap:!1,defaultDirection:"ltr"}),Object(s.extend)(this.settings,e),"object"==typeof this.settings.manager&&(this.manager=this.settings.manager),this.book=t,this.hooks={},this.hooks.display=new o.a(this),this.hooks.serialize=new o.a(this),this.hooks.content=new o.a(this),this.hooks.unloaded=new o.a(this),this.hooks.layout=new o.a(this),this.hooks.render=new o.a(this),this.hooks.show=new o.a(this),this.hooks.content.register(this.handleLinks.bind(this)),this.hooks.content.register(this.passEvents.bind(this)),this.hooks.content.register(this.adjustImages.bind(this)),this.book.spine.hooks.content.register(this.injectIdentifier.bind(this)),this.settings.stylesheet&&this.book.spine.hooks.content.register(this.injectStylesheet.bind(this)),this.settings.script&&this.book.spine.hooks.content.register(this.injectScript.bind(this)),this.themes=new f(this),this.annotations=new g(this),this.epubcfi=new a.a,this.q=new h.a(this),this.location=void 0,this.q.enqueue(this.book.opened),this.starting=new s.defer,this.started=this.starting.promise,this.q.enqueue(this.start)}setManager(t){this.manager=t}requireManager(t){return"string"==typeof t&&"default"===t?m.a:"string"==typeof t&&"continuous"===t?y.a:t}requireView(t){return"string"==typeof t&&"iframe"===t?v.a:t}start(){switch(this.settings.layout||"pre-paginated"!==this.book.package.metadata.layout&&"true"!==this.book.displayOptions.fixedLayout||(this.settings.layout="pre-paginated"),this.book.package.metadata.spread){case"none":this.settings.spread="none";break;case"both":this.settings.spread=!0}this.manager||(this.ViewManager=this.requireManager(this.settings.manager),this.View=this.requireView(this.settings.view),this.manager=new this.ViewManager({view:this.View,queue:this.q,request:this.book.load.bind(this.book),settings:this.settings})),this.direction(this.book.package.metadata.direction||this.settings.defaultDirection),this.settings.globalLayoutProperties=this.determineLayoutProperties(this.book.package.metadata),this.flow(this.settings.globalLayoutProperties.flow),this.layout(this.settings.globalLayoutProperties),this.manager.on(l.c.MANAGERS.ADDED,this.afterDisplayed.bind(this)),this.manager.on(l.c.MANAGERS.REMOVED,this.afterRemoved.bind(this)),this.manager.on(l.c.MANAGERS.RESIZED,this.onResized.bind(this)),this.manager.on(l.c.MANAGERS.ORIENTATION_CHANGE,this.onOrientationChange.bind(this)),this.manager.on(l.c.MANAGERS.SCROLLED,this.reportLocation.bind(this)),this.emit(l.c.RENDITION.STARTED),this.starting.resolve()}attachTo(t){return this.q.enqueue(function(){this.manager.render(t,{width:this.settings.width,height:this.settings.height}),this.emit(l.c.RENDITION.ATTACHED)}.bind(this))}display(t){return this.displaying&&this.displaying.resolve(),this.q.enqueue(this._display,t)}_display(t){if(this.book){this.epubcfi.isCfiString(t);var e,i=new s.defer,n=i.promise;return this.displaying=i,this.book.locations.length()&&Object(s.isFloat)(t)&&(t=this.book.locations.cfiFromPercentage(parseFloat(t))),(e=this.book.spine.get(t))?(this.manager.display(e,t).then(()=>{i.resolve(e),this.displaying=void 0,this.emit(l.c.RENDITION.DISPLAYED,e),this.reportLocation()},t=>{this.emit(l.c.RENDITION.DISPLAY_ERROR,t)}),n):(i.reject(new Error("No Section Found")),n)}}afterDisplayed(t){t.on(l.c.VIEWS.MARK_CLICKED,(e,i)=>this.triggerMarkEvent(e,i,t.contents)),this.hooks.render.trigger(t,this).then(()=>{t.contents?this.hooks.content.trigger(t.contents,this).then(()=>{this.emit(l.c.RENDITION.RENDERED,t.section,t)}):this.emit(l.c.RENDITION.RENDERED,t.section,t)})}afterRemoved(t){this.hooks.unloaded.trigger(t,this).then(()=>{this.emit(l.c.RENDITION.REMOVED,t.section,t)})}onResized(t,e){this.emit(l.c.RENDITION.RESIZED,{width:t.width,height:t.height},e),this.location&&this.location.start&&this.display(e||this.location.start.cfi)}onOrientationChange(t){this.emit(l.c.RENDITION.ORIENTATION_CHANGE,t)}moveTo(t){this.manager.moveTo(t)}resize(t,e,i){t&&(this.settings.width=t),e&&(this.settings.height=e),this.manager.resize(t,e,i)}clear(){this.manager.clear()}next(){return this.q.enqueue(this.manager.next.bind(this.manager)).then(this.reportLocation.bind(this))}prev(){return this.q.enqueue(this.manager.prev.bind(this.manager)).then(this.reportLocation.bind(this))}determineLayoutProperties(t){var e=this.settings.layout||t.layout||"reflowable",i=this.settings.spread||t.spread||"auto",n=this.settings.orientation||t.orientation||"auto",r=this.settings.flow||t.flow||"auto",s=t.viewport||"",o=this.settings.minSpreadWidth||t.minSpreadWidth||800,a=this.settings.direction||t.direction||"ltr";return(0===this.settings.width||this.settings.width>0)&&(0===this.settings.height||this.settings.height),{layout:e,spread:i,orientation:n,flow:r,viewport:s,minSpreadWidth:o,direction:a}}flow(t){var e=t;"scrolled"!==t&&"scrolled-doc"!==t&&"scrolled-continuous"!==t||(e="scrolled"),"auto"!==t&&"paginated"!==t||(e="paginated"),this.settings.flow=t,this._layout&&this._layout.flow(e),this.manager&&this._layout&&this.manager.applyLayout(this._layout),this.manager&&this.manager.updateFlow(e),this.manager&&this.manager.isRendered()&&this.location&&(this.manager.clear(),this.display(this.location.start.cfi))}layout(t){return t&&(this._layout=new u(t),this._layout.spread(t.spread,this.settings.minSpreadWidth),this._layout.on(l.c.LAYOUT.UPDATED,(t,e)=>{this.emit(l.c.RENDITION.LAYOUT,t,e)})),this.manager&&this._layout&&this.manager.applyLayout(this._layout),this._layout}spread(t,e){this.settings.spread=t,e&&(this.settings.minSpreadWidth=e),this._layout&&this._layout.spread(t,e),this.manager&&this.manager.isRendered()&&this.manager.updateLayout()}direction(t){this.settings.direction=t||"ltr",this.manager&&this.manager.direction(this.settings.direction),this.manager&&this.manager.isRendered()&&this.location&&(this.manager.clear(),this.display(this.location.start.cfi))}reportLocation(){return this.q.enqueue(function(){requestAnimationFrame(function(){var t=this.manager.currentLocation();if(t&&t.then&&"function"==typeof t.then)t.then(function(t){let e=this.located(t);e&&e.start&&e.end&&(this.location=e,this.emit(l.c.RENDITION.LOCATION_CHANGED,{index:this.location.start.index,href:this.location.start.href,start:this.location.start.cfi,end:this.location.end.cfi,percentage:this.location.start.percentage}),this.emit(l.c.RENDITION.RELOCATED,this.location))}.bind(this));else if(t){let e=this.located(t);if(!e||!e.start||!e.end)return;this.location=e,this.emit(l.c.RENDITION.LOCATION_CHANGED,{index:this.location.start.index,href:this.location.start.href,start:this.location.start.cfi,end:this.location.end.cfi,percentage:this.location.start.percentage}),this.emit(l.c.RENDITION.RELOCATED,this.location)}}.bind(this))}.bind(this))}currentLocation(){var t=this.manager.currentLocation();if(t&&t.then&&"function"==typeof t.then)t.then(function(t){return this.located(t)}.bind(this));else if(t){return this.located(t)}}located(t){if(!t.length)return{};let e=t[0],i=t[t.length-1],n={start:{index:e.index,href:e.href,cfi:e.mapping.start,displayed:{page:e.pages[0]||1,total:e.totalPages}},end:{index:i.index,href:i.href,cfi:i.mapping.end,displayed:{page:i.pages[i.pages.length-1]||1,total:i.totalPages}}},r=this.book.locations.locationFromCfi(e.mapping.start),s=this.book.locations.locationFromCfi(i.mapping.end);null!=r&&(n.start.location=r,n.start.percentage=this.book.locations.percentageFromLocation(r)),null!=s&&(n.end.location=s,n.end.percentage=this.book.locations.percentageFromLocation(s));let o=this.book.pageList.pageFromCfi(e.mapping.start),a=this.book.pageList.pageFromCfi(i.mapping.end);return-1!=o&&(n.start.page=o),-1!=a&&(n.end.page=a),i.index===this.book.spine.last().index&&n.end.displayed.page>=n.end.displayed.total&&(n.atEnd=!0),e.index===this.book.spine.first().index&&1===n.start.displayed.page&&(n.atStart=!0),n}destroy(){this.manager&&this.manager.destroy(),this.book=void 0}passEvents(t){l.a.forEach(e=>{t.on(e,e=>this.triggerViewEvent(e,t))}),t.on(l.c.CONTENTS.SELECTED,e=>this.triggerSelectedEvent(e,t))}triggerViewEvent(t,e){this.emit(t.type,t,e)}triggerSelectedEvent(t,e){this.emit(l.c.RENDITION.SELECTED,t,e)}triggerMarkEvent(t,e,i){this.emit(l.c.RENDITION.MARK_CLICKED,t,e,i)}getRange(t,e){var i=new a.a(t),n=this.manager.visible().filter((function(t){if(i.spinePos===t.index)return!0}));if(n.length)return n[0].contents.range(i,e)}adjustImages(t){if("pre-paginated"===this._layout.name)return new Promise((function(t){t()}));let e=t.window.getComputedStyle(t.content,null),i=.95*(t.content.offsetHeight-(parseFloat(e.paddingTop)+parseFloat(e.paddingBottom))),n=parseFloat(e.paddingLeft)+parseFloat(e.paddingRight);return t.addStylesheetRules({img:{"max-width":(this._layout.columnWidth?this._layout.columnWidth-n+"px":"100%")+"!important","max-height":i+"px!important","object-fit":"contain","page-break-inside":"avoid","break-inside":"avoid","box-sizing":"border-box"},svg:{"max-width":(this._layout.columnWidth?this._layout.columnWidth-n+"px":"100%")+"!important","max-height":i+"px!important","page-break-inside":"avoid","break-inside":"avoid"}}),new Promise((function(t,e){setTimeout((function(){t()}),1)}))}getContents(){return this.manager?this.manager.getContents():[]}views(){return(this.manager?this.manager.views:void 0)||[]}handleLinks(t){t&&t.on(l.c.CONTENTS.LINK_CLICKED,t=>{let e=this.book.path.relative(t);this.display(e)})}injectStylesheet(t,e){let i=t.createElement("link");i.setAttribute("type","text/css"),i.setAttribute("rel","stylesheet"),i.setAttribute("href",this.settings.stylesheet),t.getElementsByTagName("head")[0].appendChild(i)}injectScript(t,e){let i=t.createElement("script");i.setAttribute("type","text/javascript"),i.setAttribute("src",this.settings.script),i.textContent=" ",t.getElementsByTagName("head")[0].appendChild(i)}injectIdentifier(t,e){let i=this.book.packaging.metadata.identifier,n=t.createElement("meta");n.setAttribute("name","dc.relation.ispartof"),i&&n.setAttribute("content",i),t.getElementsByTagName("head")[0].appendChild(n)}}r()(b.prototype);e.a=b},function(t,e){var i={}.toString;t.exports=function(t){return i.call(t).slice(8,-1)}},function(t,e,i){var n=i(17);t.exports=function(t,e){if(!n(t))return t;var i,r;if(e&&"function"==typeof(i=t.toString)&&!n(r=i.call(t)))return r;if("function"==typeof(i=t.valueOf)&&!n(r=i.call(t)))return r;if(!e&&"function"==typeof(i=t.toString)&&!n(r=i.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},function(t,e,i){var n=i(7),r=i(15);t.exports=function(t,e){try{r(n,t,e)}catch(i){n[t]=e}return e}},function(t,e,i){var n=i(66),r=i(67),s=n("keys");t.exports=function(t){return s[t]||(s[t]=r(t))}},function(t,e){t.exports={}},function(t,e,i){var n=i(92),r=i(7),s=function(t){return"function"==typeof t?t:void 0};t.exports=function(t,e){return arguments.length<2?s(n[t])||s(r[t]):n[t]&&n[t][e]||r[t]&&r[t][e]}},function(t,e,i){var n=i(35),r=Math.min;t.exports=function(t){return t>0?r(n(t),9007199254740991):0}},function(t,e){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(t,e,i){"use strict";var n,r,s=i(97),o=i(98),a=RegExp.prototype.exec,h=String.prototype.replace,l=a,c=(n=/a/,r=/b*/g,a.call(n,"a"),a.call(r,"a"),0!==n.lastIndex||0!==r.lastIndex),u=o.UNSUPPORTED_Y||o.BROKEN_CARET,d=void 0!==/()??/.exec("")[1];(c||d||u)&&(l=function(t){var e,i,n,r,o=this,l=u&&o.sticky,f=s.call(o),p=o.source,g=0,v=t;return l&&(-1===(f=f.replace("y","")).indexOf("g")&&(f+="g"),v=String(t).slice(o.lastIndex),o.lastIndex>0&&(!o.multiline||o.multiline&&"\n"!==t[o.lastIndex-1])&&(p="(?: "+p+")",v=" "+v,g++),i=new RegExp("^(?:"+p+")",f)),d&&(i=new RegExp("^"+p+"$(?!\\s)",f)),c&&(e=o.lastIndex),n=a.call(l?i:o,v),l?n?(n.input=n.input.slice(g),n[0]=n[0].slice(g),n.index=o.lastIndex,o.lastIndex+=n[0].length):o.lastIndex=0:c&&n&&(o.lastIndex=o.global?n.index+n[0].length:e),d&&n&&n.length>1&&h.call(n[0],i,(function(){for(r=1;r=l?t?"":void 0:(s=a.charCodeAt(h))<55296||s>56319||h+1===l||(o=a.charCodeAt(h+1))<56320||o>57343?t?a.charAt(h):s:t?a.slice(h,h+2):o-56320+(s-55296<<10)+65536}};t.exports={codeAt:s(!1),charAt:s(!0)}},function(t,e,i){var n,r=i(13),s=i(72),o=i(47),a=i(44),h=i(104),l=i(63),c=i(43),u=c("IE_PROTO"),d=function(){},f=function(t){return" + + SillyTavern + + + +
+
+
+
+
+

+ + Welcome to SillyTavern +

+

+ Select an Account +

+

+ Enter Login Details +

+
+
+ + + +
+
+
+
+
+
+
+ + + diff --git a/public/script.js b/public/script.js index 31344684a..9bbb8dfa0 100644 --- a/public/script.js +++ b/public/script.js @@ -202,7 +202,7 @@ import { instruct_presets, selectContextPreset, } from './scripts/instruct-mode.js'; -import { applyLocale, initLocales } from './scripts/i18n.js'; +import { initLocales } from './scripts/i18n.js'; import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, getTokenizerModel, initTokenizers, saveTokenCache } from './scripts/tokenizers.js'; import { createPersona, initPersonas, selectCurrentPersona, setPersonaDescription, updatePersonaNameIfExists } from './scripts/personas.js'; import { getBackgrounds, initBackgrounds, loadBackgroundSettings, background_settings } from './scripts/backgrounds.js'; @@ -212,8 +212,10 @@ import { loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermati import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId } from './scripts/chats.js'; import { initPresetManager } from './scripts/preset-manager.js'; import { evaluateMacros } from './scripts/macros.js'; +import { currentUser, setUserControls } from './scripts/user.js'; import { callGenericPopup } from './scripts/popup.js'; import { renderTemplate, renderTemplateAsync } from './scripts/templates.js'; +import { ScraperManager } from './scripts/scrapers.js'; //exporting functions and vars for mods export { @@ -446,6 +448,7 @@ export const event_types = { CHARACTER_DELETED: 'characterDeleted', CHARACTER_DUPLICATED: 'character_duplicated', SMOOTH_STREAM_TOKEN_RECEIVED: 'smooth_stream_token_received', + FILE_ATTACHMENT_DELETED: 'file_attachment_deleted', }; export const eventSource = new EventEmitter(); @@ -666,13 +669,15 @@ async function getSystemMessages() { registerPromptManagerMigration(); $(document).ajaxError(function myErrorHandler(_, xhr) { + // Cohee: CSRF doesn't error out in multiple tabs anymore, so this is unnecessary + /* if (xhr.status == 403) { toastr.warning( 'doubleCsrf errors in console are NORMAL in this case. If you want to run ST in multiple tabs, start the server with --disableCsrf option.', 'Looks like you\'ve opened SillyTavern in another browser tab', { timeOut: 0, extendedTimeOut: 0, preventDuplicates: true }, ); - } + } */ }); async function getClientVersion() { @@ -1501,7 +1506,7 @@ function getCharacterSource(chId = this_chid) { } async function getCharacters() { - var response = await fetch('/api/characters/all', { + const response = await fetch('/api/characters/all', { method: 'POST', headers: getRequestHeaders(), body: JSON.stringify({ @@ -1509,11 +1514,9 @@ async function getCharacters() { }), }); if (response.ok === true) { - var getData = ''; //RossAscends: reset to force array to update to account for deleted character. - getData = await response.json(); - const load_ch_count = Object.getOwnPropertyNames(getData); - for (var i = 0; i < load_ch_count.length; i++) { - characters[i] = []; + characters.splice(0, characters.length); + const getData = await response.json(); + for (let i = 0; i < getData.length; i++) { characters[i] = getData[i]; characters[i]['name'] = DOMPurify.sanitize(characters[i]['name']); @@ -6079,7 +6082,7 @@ async function doOnboarding(avatarId) { template.find('input[name="enable_simple_mode"]').on('input', function () { simpleUiMode = $(this).is(':checked'); }); - var userName = await callPopup(template, 'input', name1); + let userName = await callPopup(template, 'input', currentUser?.name || name1); if (userName) { userName = userName.replace('\n', ' '); @@ -6133,6 +6136,8 @@ async function getSettings() { $('#your_name').val(name1); } + await setUserControls(data.enable_accounts); + // Allow subscribers to mutate settings eventSource.emit(event_types.SETTINGS_LOADED_BEFORE, settings); @@ -7090,10 +7095,10 @@ function onScenarioOverrideRemoveClick() { * @param {string} type * @param {string} inputValue - Value to set the input to. * @param {PopupOptions} options - Options for the popup. - * @typedef {{okButton?: string, rows?: number, wide?: boolean, large?: boolean, allowHorizontalScrolling?: boolean, allowVerticalScrolling?: boolean }} PopupOptions - Options for the popup. + * @typedef {{okButton?: string, rows?: number, wide?: boolean, large?: boolean, allowHorizontalScrolling?: boolean, allowVerticalScrolling?: boolean, cropAspect?: number }} PopupOptions - Options for the popup. * @returns */ -function callPopup(text, type, inputValue = '', { okButton, rows, wide, large, allowHorizontalScrolling, allowVerticalScrolling } = {}) { +function callPopup(text, type, inputValue = '', { okButton, rows, wide, large, allowHorizontalScrolling, allowVerticalScrolling, cropAspect } = {}) { dialogueCloseStop = true; if (type) { popup_type = type; @@ -7150,7 +7155,7 @@ function callPopup(text, type, inputValue = '', { okButton, rows, wide, large, a crop_data = undefined; $('#avatarToCrop').cropper({ - aspectRatio: 2 / 3, + aspectRatio: cropAspect ?? 2 / 3, autoCropArea: 1, viewMode: 2, rotatable: false, @@ -7362,47 +7367,6 @@ export function cancelTtsPlay() { } } -async function deleteMessageImage() { - const value = await callPopup('

Delete image from message?
This action can\'t be undone.

', 'confirm'); - - if (!value) { - return; - } - - const mesBlock = $(this).closest('.mes'); - const mesId = mesBlock.attr('mesid'); - const message = chat[mesId]; - delete message.extra.image; - delete message.extra.inline_image; - mesBlock.find('.mes_img_container').removeClass('img_extra'); - mesBlock.find('.mes_img').attr('src', ''); - await saveChatConditional(); -} - -function enlargeMessageImage() { - const mesBlock = $(this).closest('.mes'); - const mesId = mesBlock.attr('mesid'); - const message = chat[mesId]; - const imgSrc = message?.extra?.image; - const title = message?.extra?.title; - - if (!imgSrc) { - return; - } - - const img = document.createElement('img'); - img.classList.add('img_enlarged'); - img.src = imgSrc; - const imgContainer = $('
'); - imgContainer.prepend(img); - imgContainer.addClass('img_enlarged_container'); - imgContainer.find('code').addClass('txt').text(title); - const titleEmpty = !title || title.trim().length === 0; - imgContainer.find('pre').toggle(!titleEmpty); - addCopyToCodeBlocks(imgContainer); - callPopup(imgContainer, 'text', '', { wide: true, large: true }); -} - function updateAlternateGreetingsHintVisibility(root) { const numberOfGreetings = root.find('.alternate_greetings_list .alternate_greeting').length; $(root).find('.alternate_grettings_hint').toggle(numberOfGreetings == 0); @@ -7798,6 +7762,7 @@ window['SillyTavern'].getContext = function () { */ renderExtensionTemplate: renderExtensionTemplate, renderExtensionTemplateAsync: renderExtensionTemplateAsync, + registerDataBankScraper: ScraperManager.registerDataBankScraper, callPopup: callPopup, callGenericPopup: callGenericPopup, mainApi: main_api, @@ -10162,6 +10127,7 @@ jQuery(async function () { '#character_cross', '#avatar-and-name-block', '#shadow_popup', + '.shadow_popup', '#world_popup', '.ui-widget', '.text_pole', @@ -10397,9 +10363,6 @@ jQuery(async function () { $('#char-management-dropdown').prop('selectedIndex', 0); }); - $(document).on('click', '.mes_img_enlarge', enlargeMessageImage); - $(document).on('click', '.mes_img_delete', deleteMessageImage); - $(window).on('beforeunload', () => { cancelTtsPlay(); if (streamingProcessor) { diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js index 94c958579..7c12d5763 100644 --- a/public/scripts/RossAscends-mods.js +++ b/public/scripts/RossAscends-mods.js @@ -32,7 +32,7 @@ import { SECRET_KEYS, secret_state, } from './secrets.js'; -import { debounce, delay, getStringHash, isValidUrl } from './utils.js'; +import { debounce, getStringHash, isValidUrl } from './utils.js'; import { chat_completion_sources, oai_settings } from './openai.js'; import { getTokenCountAsync } from './tokenizers.js'; import { textgen_types, textgenerationwebui_settings as textgen_settings, getTextGenServer } from './textgen-settings.js'; diff --git a/public/scripts/bulk-edit.js b/public/scripts/bulk-edit.js index f09e290df..891a6134a 100644 --- a/public/scripts/bulk-edit.js +++ b/public/scripts/bulk-edit.js @@ -1,4 +1,4 @@ -import { characters, getCharacters, handleDeleteCharacter, callPopup, characterGroupOverlay } from '../script.js'; +import { characterGroupOverlay } from '../script.js'; import { BulkEditOverlay, BulkEditOverlayState } from './BulkEditOverlay.js'; @@ -69,15 +69,6 @@ function onSelectAllButtonClick() { } } -/** - * Deletes the character with the given chid. - * - * @param {string} this_chid - The chid of the character to delete. - */ -async function deleteCharacter(this_chid) { - await handleDeleteCharacter('del_ch', this_chid, false); -} - /** * Deletes all characters that have been selected via the bulk checkboxes. */ diff --git a/public/scripts/chats.js b/public/scripts/chats.js index ac00b74a6..a4082f6f0 100644 --- a/public/scripts/chats.js +++ b/public/scripts/chats.js @@ -18,6 +18,8 @@ import { saveSettingsDebounced, showSwipeButtons, this_chid, + saveChatConditional, + chat_metadata, } from '../script.js'; import { selected_group } from './group-chats.js'; import { power_user } from './power-user.js'; @@ -25,22 +27,93 @@ import { extractTextFromHTML, extractTextFromMarkdown, extractTextFromPDF, + extractTextFromEpub, getBase64Async, getStringHash, humanFileSize, saveBase64AsFile, + extractTextFromOffice, } from './utils.js'; +import { extension_settings, renderExtensionTemplateAsync, saveMetadataDebounced } from './extensions.js'; +import { POPUP_RESULT, POPUP_TYPE, callGenericPopup } from './popup.js'; +import { ScraperManager } from './scrapers.js'; + +/** + * @typedef {Object} FileAttachment + * @property {string} url File URL + * @property {number} size File size + * @property {string} name File name + * @property {number} created Timestamp + * @property {string} [text] File text + */ + +/** + * @typedef {function} ConverterFunction + * @param {File} file File object + * @returns {Promise} Converted file text + */ const fileSizeLimit = 1024 * 1024 * 10; // 10 MB +const ATTACHMENT_SOURCE = { + GLOBAL: 'global', + CHAT: 'chat', + CHARACTER: 'character', +}; +/** + * @type {Record} File converters + */ const converters = { 'application/pdf': extractTextFromPDF, 'text/html': extractTextFromHTML, 'text/markdown': extractTextFromMarkdown, + 'application/epub+zip': extractTextFromEpub, + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': extractTextFromOffice, + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': extractTextFromOffice, + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': extractTextFromOffice, + 'application/vnd.oasis.opendocument.text': extractTextFromOffice, + 'application/vnd.oasis.opendocument.presentation': extractTextFromOffice, + 'application/vnd.oasis.opendocument.spreadsheet': extractTextFromOffice, }; +/** + * Finds a matching key in the converters object. + * @param {string} type MIME type + * @returns {string} Matching key + */ +function findConverterKey(type) { + return Object.keys(converters).find((key) => { + // Match exact type + if (type === key) { + return true; + } + + // Match wildcards + if (key.endsWith('*')) { + return type.startsWith(key.substring(0, key.length - 1)); + } + + return false; + }); +} + +/** + * Determines if the file type has a converter function. + * @param {string} type MIME type + * @returns {boolean} True if the file type is convertible, false otherwise. + */ function isConvertible(type) { - return Object.keys(converters).includes(type); + return Boolean(findConverterKey(type)); +} + +/** + * Gets the converter function for a file type. + * @param {string} type MIME type + * @returns {ConverterFunction} Converter function + */ +function getConverter(type) { + const key = findConverterKey(type); + return key && converters[key]; } /** @@ -126,7 +199,7 @@ export async function populateFileAttachment(message, inputId = 'file_form_input if (isConvertible(file.type)) { try { - const converter = converters[file.type]; + const converter = getConverter(file.type); const fileText = await converter(file); base64Data = window.btoa(unescape(encodeURIComponent(fileText))); } catch (error) { @@ -145,6 +218,7 @@ export async function populateFileAttachment(message, inputId = 'file_form_input url: fileUrl, size: file.size, name: file.name, + created: Date.now(), }; } @@ -275,9 +349,9 @@ async function onFileAttach() { * @param {number} messageId Message ID */ async function deleteMessageFile(messageId) { - const confirm = await callPopup('Are you sure you want to delete this file?', 'confirm'); + const confirm = await callGenericPopup('Are you sure you want to delete this file?', POPUP_TYPE.CONFIRM); - if (!confirm) { + if (confirm !== POPUP_RESULT.AFFIRMATIVE) { console.debug('Delete file cancelled'); return; } @@ -289,11 +363,15 @@ async function deleteMessageFile(messageId) { return; } + const url = message.extra.file.url; + delete message.extra.file; $(`.mes[mesid="${messageId}"] .mes_file_container`).remove(); - saveChatDebounced(); + await saveChatConditional(); + await deleteFileFromServer(url); } + /** * Opens file from message in a modal. * @param {number} messageId Message ID @@ -306,14 +384,7 @@ async function viewMessageFile(messageId) { return; } - const fileText = messageFile.text || (await getFileAttachment(messageFile.url)); - - const modalTemplate = $('
'); - modalTemplate.find('code').addClass('txt').text(fileText); - modalTemplate.addClass('file_modal'); - addCopyToCodeBlocks(modalTemplate); - - callPopup(modalTemplate, 'text', '', { wide: true, large: true }); + await openFilePopup(messageFile); } /** @@ -348,7 +419,7 @@ function embedMessageFile(messageId, messageBlock) { await populateFileAttachment(message, 'embed_file_input'); appendMediaToMessage(message, messageBlock); - saveChatDebounced(); + await saveChatConditional(); } } @@ -363,7 +434,7 @@ export async function appendFileContent(message, messageText) { const fileText = message.extra.file.text || (await getFileAttachment(message.extra.file.url)); if (fileText) { - const fileWrapped = `\`\`\`\n${fileText}\n\`\`\`\n\n`; + const fileWrapped = `${fileText}\n\n`; message.extra.fileLength = fileWrapped.length; messageText = fileWrapped + messageText; } @@ -395,7 +466,7 @@ export function decodeStyleTags(text) { return text.replaceAll(styleDecodeRegex, (_, style) => { try { - let styleCleaned = unescape(style).replaceAll(//g, ''); + let styleCleaned = unescape(style).replaceAll(//g, ''); const ast = css.parse(styleCleaned); const rules = ast?.stylesheet?.rules; if (rules) { @@ -436,8 +507,8 @@ async function openExternalMediaOverridesDialog() { } const template = $('#forbid_media_override_template > .forbid_media_override').clone(); - template.find('.forbid_media_global_state_forbidden').toggle(power_user.forbid_external_images); - template.find('.forbid_media_global_state_allowed').toggle(!power_user.forbid_external_images); + template.find('.forbid_media_global_state_forbidden').toggle(power_user.forbid_external_media); + template.find('.forbid_media_global_state_allowed').toggle(!power_user.forbid_external_media); if (power_user.external_media_allowed_overrides.includes(entityId)) { template.find('#forbid_media_override_allowed').prop('checked', true); @@ -463,7 +534,7 @@ export function getCurrentEntityId() { export function isExternalMediaAllowed() { const entityId = getCurrentEntityId(); if (!entityId) { - return !power_user.forbid_external_images; + return !power_user.forbid_external_media; } if (power_user.external_media_allowed_overrides.includes(entityId)) { @@ -474,7 +545,518 @@ export function isExternalMediaAllowed() { return false; } - return !power_user.forbid_external_images; + return !power_user.forbid_external_media; +} + +function enlargeMessageImage() { + const mesBlock = $(this).closest('.mes'); + const mesId = mesBlock.attr('mesid'); + const message = chat[mesId]; + const imgSrc = message?.extra?.image; + const title = message?.extra?.title; + + if (!imgSrc) { + return; + } + + const img = document.createElement('img'); + img.classList.add('img_enlarged'); + img.src = imgSrc; + const imgContainer = $('
'); + imgContainer.prepend(img); + imgContainer.addClass('img_enlarged_container'); + imgContainer.find('code').addClass('txt').text(title); + const titleEmpty = !title || title.trim().length === 0; + imgContainer.find('pre').toggle(!titleEmpty); + addCopyToCodeBlocks(imgContainer); + callGenericPopup(imgContainer, POPUP_TYPE.TEXT, '', { wide: true, large: true }); +} + +async function deleteMessageImage() { + const value = await callGenericPopup('

Delete image from message?
This action can\'t be undone.

', POPUP_TYPE.CONFIRM); + + if (value !== POPUP_RESULT.AFFIRMATIVE) { + return; + } + + const mesBlock = $(this).closest('.mes'); + const mesId = mesBlock.attr('mesid'); + const message = chat[mesId]; + delete message.extra.image; + delete message.extra.inline_image; + mesBlock.find('.mes_img_container').removeClass('img_extra'); + mesBlock.find('.mes_img').attr('src', ''); + await saveChatConditional(); +} + +/** + * Deletes file from the server. + * @param {string} url Path to the file on the server + * @returns {Promise} True if file was deleted, false otherwise. + */ +async function deleteFileFromServer(url) { + try { + const result = await fetch('/api/files/delete', { + method: 'POST', + headers: getRequestHeaders(), + body: JSON.stringify({ path: url }), + }); + + if (!result.ok) { + const error = await result.text(); + throw new Error(error); + } + + await eventSource.emit(event_types.FILE_ATTACHMENT_DELETED, url); + return true; + } catch (error) { + toastr.error(String(error), 'Could not delete file'); + console.error('Could not delete file', error); + return false; + } +} + +/** + * Opens file attachment in a modal. + * @param {FileAttachment} attachment File attachment + */ +async function openFilePopup(attachment) { + const fileText = attachment.text || (await getFileAttachment(attachment.url)); + + const modalTemplate = $('
'); + modalTemplate.find('code').addClass('txt').text(fileText); + modalTemplate.addClass('file_modal').addClass('textarea_compact').addClass('fontsize90p'); + addCopyToCodeBlocks(modalTemplate); + + callGenericPopup(modalTemplate, POPUP_TYPE.TEXT, '', { wide: true, large: true }); +} + +/** + * Edit a file attachment in a notepad-like modal. + * @param {FileAttachment} attachment Attachment to edit + * @param {string} source Attachment source + * @param {function} callback Callback function + */ +async function editAttachment(attachment, source, callback) { + const originalFileText = attachment.text || (await getFileAttachment(attachment.url)); + const template = $(await renderExtensionTemplateAsync('attachments', 'notepad')); + + let editedFileText = originalFileText; + template.find('[name="notepadFileContent"]').val(editedFileText).on('input', function () { + editedFileText = String($(this).val()); + }); + + let editedFileName = attachment.name; + template.find('[name="notepadFileName"]').val(editedFileName).on('input', function () { + editedFileName = String($(this).val()); + }); + + const result = await callGenericPopup(template, POPUP_TYPE.CONFIRM, '', { wide: true, large: true, okButton: 'Save', cancelButton: 'Cancel' }); + + if (result !== POPUP_RESULT.AFFIRMATIVE) { + return; + } + + if (editedFileText === originalFileText && editedFileName === attachment.name) { + return; + } + + const nullCallback = () => { }; + await deleteAttachment(attachment, source, nullCallback, false); + const file = new File([editedFileText], editedFileName, { type: 'text/plain' }); + await uploadFileAttachmentToServer(file, source); + + callback(); +} + +/** + * Deletes an attachment from the server and the chat. + * @param {FileAttachment} attachment Attachment to delete + * @param {string} source Source of the attachment + * @param {function} callback Callback function + * @param {boolean} [confirm=true] If true, show a confirmation dialog + * @returns {Promise} A promise that resolves when the attachment is deleted. + */ +async function deleteAttachment(attachment, source, callback, confirm = true) { + if (confirm) { + const result = await callGenericPopup('Are you sure you want to delete this attachment?', POPUP_TYPE.CONFIRM); + + if (result !== POPUP_RESULT.AFFIRMATIVE) { + return; + } + } + + ensureAttachmentsExist(); + + switch (source) { + case 'global': + extension_settings.attachments = extension_settings.attachments.filter((a) => a.url !== attachment.url); + saveSettingsDebounced(); + break; + case 'chat': + chat_metadata.attachments = chat_metadata.attachments.filter((a) => a.url !== attachment.url); + saveMetadataDebounced(); + break; + case 'character': + extension_settings.character_attachments[characters[this_chid]?.avatar] = extension_settings.character_attachments[characters[this_chid]?.avatar].filter((a) => a.url !== attachment.url); + break; + } + + await deleteFileFromServer(attachment.url); + callback(); +} + +/** + * Opens the attachment manager. + */ +async function openAttachmentManager() { + /** + * Renders a list of attachments. + * @param {FileAttachment[]} attachments List of attachments + * @param {string} source Source of the attachments + */ + async function renderList(attachments, source) { + /** + * Sorts attachments by sortField and sortOrder. + * @param {FileAttachment} a First attachment + * @param {FileAttachment} b Second attachment + * @returns {number} Sort order + */ + function sortFn(a, b) { + const sortValueA = a[sortField]; + const sortValueB = b[sortField]; + if (typeof sortValueA === 'string' && typeof sortValueB === 'string') { + return sortValueA.localeCompare(sortValueB) * (sortOrder === 'asc' ? 1 : -1); + } + return (sortValueA - sortValueB) * (sortOrder === 'asc' ? 1 : -1); + } + + /** + * Filters attachments by name. + * @param {FileAttachment} a Attachment + * @returns {boolean} True if attachment matches the filter, false otherwise. + */ + function filterFn(a) { + if (!filterString) { + return true; + } + + return a.name.toLowerCase().includes(filterString.toLowerCase()); + } + const sources = { + [ATTACHMENT_SOURCE.GLOBAL]: '.globalAttachmentsList', + [ATTACHMENT_SOURCE.CHARACTER]: '.characterAttachmentsList', + [ATTACHMENT_SOURCE.CHAT]: '.chatAttachmentsList', + }; + + template.find(sources[source]).empty(); + + // Sort attachments by sortField and sortOrder, and apply filter + const sortedAttachmentList = attachments.slice().filter(filterFn).sort(sortFn); + + for (const attachment of sortedAttachmentList) { + const attachmentTemplate = template.find('.attachmentListItemTemplate .attachmentListItem').clone(); + attachmentTemplate.find('.attachmentListItemName').text(attachment.name); + attachmentTemplate.find('.attachmentListItemSize').text(humanFileSize(attachment.size)); + attachmentTemplate.find('.attachmentListItemCreated').text(new Date(attachment.created).toLocaleString()); + attachmentTemplate.find('.viewAttachmentButton').on('click', () => openFilePopup(attachment)); + attachmentTemplate.find('.editAttachmentButton').on('click', () => editAttachment(attachment, source, renderAttachments)); + attachmentTemplate.find('.deleteAttachmentButton').on('click', () => deleteAttachment(attachment, source, renderAttachments)); + template.find(sources[source]).append(attachmentTemplate); + } + } + + /** + * Renders buttons for the attachment manager. + */ + async function renderButtons() { + const sources = { + [ATTACHMENT_SOURCE.GLOBAL]: '.globalAttachmentsTitle', + [ATTACHMENT_SOURCE.CHARACTER]: '.characterAttachmentsTitle', + [ATTACHMENT_SOURCE.CHAT]: '.chatAttachmentsTitle', + }; + + const modal = template.find('.actionButtonsModal').hide(); + const scrapers = ScraperManager.getDataBankScrapers(); + + for (const scraper of scrapers) { + const isAvailable = await ScraperManager.isScraperAvailable(scraper.id); + if (!isAvailable) { + continue; + } + + const buttonTemplate = template.find('.actionButtonTemplate .actionButton').clone(); + buttonTemplate.find('.actionButtonIcon').addClass(scraper.iconClass); + buttonTemplate.find('.actionButtonText').text(scraper.name); + buttonTemplate.attr('title', scraper.description); + buttonTemplate.on('click', () => { + const target = modal.attr('data-attachment-manager-target'); + runScraper(scraper.id, target, renderAttachments); + }); + modal.append(buttonTemplate); + } + + const modalButtonData = Object.entries(sources).map(entry => { + const [source, selector] = entry; + const button = template.find(selector).find('.openActionModalButton').get(0); + + if (!button) { + return; + } + + const bodyListener = (e) => { + if (modal.is(':visible') && (!$(e.target).closest('.openActionModalButton').length)) { + modal.hide(); + } + + // Replay a click if the modal was already open by another button + if ($(e.target).closest('.openActionModalButton').length && !modal.is(':visible')) { + modal.show(); + } + }; + document.body.addEventListener('click', bodyListener); + + const popper = Popper.createPopper(button, modal.get(0), { placement: 'bottom-end' }); + button.addEventListener('click', () => { + modal.attr('data-attachment-manager-target', source); + modal.toggle(); + popper.update(); + }); + + return [popper, bodyListener]; + }).filter(Boolean); + + return () => { + modalButtonData.forEach(p => { + const [popper, bodyListener] = p; + popper.destroy(); + document.body.removeEventListener('click', bodyListener); + }); + modal.remove(); + }; + } + + async function renderAttachments() { + /** @type {FileAttachment[]} */ + const globalAttachments = extension_settings.attachments ?? []; + /** @type {FileAttachment[]} */ + const chatAttachments = chat_metadata.attachments ?? []; + /** @type {FileAttachment[]} */ + const characterAttachments = extension_settings.character_attachments?.[characters[this_chid]?.avatar] ?? []; + + await renderList(globalAttachments, ATTACHMENT_SOURCE.GLOBAL); + await renderList(chatAttachments, ATTACHMENT_SOURCE.CHAT); + await renderList(characterAttachments, ATTACHMENT_SOURCE.CHARACTER); + + const isNotCharacter = this_chid === undefined || selected_group; + const isNotInChat = getCurrentChatId() === undefined; + template.find('.characterAttachmentsBlock').toggle(!isNotCharacter); + template.find('.chatAttachmentsBlock').toggle(!isNotInChat); + + const characterName = characters[this_chid]?.name || 'Anonymous'; + template.find('.characterAttachmentsName').text(characterName); + + const chatName = getCurrentChatId() || 'Unnamed chat'; + template.find('.chatAttachmentsName').text(chatName); + } + + let sortField = localStorage.getItem('DataBank_sortField') || 'created'; + let sortOrder = localStorage.getItem('DataBank_sortOrder') || 'desc'; + let filterString = ''; + + const template = $(await renderExtensionTemplateAsync('attachments', 'manager', {})); + + template.find('.attachmentSearch').on('input', function () { + filterString = String($(this).val()); + renderAttachments(); + }); + template.find('.attachmentSort').on('change', function () { + if (!(this instanceof HTMLSelectElement) || this.selectedOptions.length === 0) { + return; + } + + sortField = this.selectedOptions[0].dataset.sortField; + sortOrder = this.selectedOptions[0].dataset.sortOrder; + localStorage.setItem('DataBank_sortField', sortField); + localStorage.setItem('DataBank_sortOrder', sortOrder); + renderAttachments(); + }); + + const cleanupFn = await renderButtons(); + await renderAttachments(); + await callGenericPopup(template, POPUP_TYPE.TEXT, '', { wide: true, large: true, okButton: 'Close' }); + + cleanupFn(); +} + +/** + * Runs a known scraper on a source and saves the result as an attachment. + * @param {string} scraperId Id of the scraper + * @param {string} target Target for the attachment + * @param {function} callback Callback function + * @returns {Promise} A promise that resolves when the source is scraped. + */ +async function runScraper(scraperId, target, callback) { + try { + console.log(`Running scraper ${scraperId} for ${target}`); + const files = await ScraperManager.runDataBankScraper(scraperId); + + if (!Array.isArray(files)) { + console.warn('Scraping returned nothing'); + return; + } + + if (files.length === 0) { + console.warn('Scraping returned no files'); + toastr.info('No files were scraped.', 'Data Bank'); + return; + } + + for (const file of files) { + await uploadFileAttachmentToServer(file, target); + } + + toastr.success(`Scraped ${files.length} files from ${scraperId} to ${target}.`, 'Data Bank'); + callback(); + } + catch (error) { + console.error('Scraping failed', error); + toastr.error('Check browser console for details.', 'Scraping failed'); + } +} + +/** + * Uploads a file attachment to the server. + * @param {File} file File to upload + * @param {string} target Target for the attachment + * @returns + */ +export async function uploadFileAttachmentToServer(file, target) { + const isValid = await validateFile(file); + + if (!isValid) { + return; + } + + let base64Data = await getBase64Async(file); + const slug = getStringHash(file.name); + const uniqueFileName = `${Date.now()}_${slug}.txt`; + + if (isConvertible(file.type)) { + try { + const converter = getConverter(file.type); + const fileText = await converter(file); + base64Data = window.btoa(unescape(encodeURIComponent(fileText))); + } catch (error) { + toastr.error(String(error), 'Could not convert file'); + console.error('Could not convert file', error); + } + } else { + const fileText = await file.text(); + base64Data = window.btoa(unescape(encodeURIComponent(fileText))); + } + + const fileUrl = await uploadFileAttachment(uniqueFileName, base64Data); + const convertedSize = Math.round(base64Data.length * 0.75); + + if (!fileUrl) { + return; + } + + const attachment = { + url: fileUrl, + size: convertedSize, + name: file.name, + created: Date.now(), + }; + + ensureAttachmentsExist(); + + switch (target) { + case ATTACHMENT_SOURCE.GLOBAL: + extension_settings.attachments.push(attachment); + saveSettingsDebounced(); + break; + case ATTACHMENT_SOURCE.CHAT: + chat_metadata.attachments.push(attachment); + saveMetadataDebounced(); + break; + case ATTACHMENT_SOURCE.CHARACTER: + extension_settings.character_attachments[characters[this_chid]?.avatar].push(attachment); + saveSettingsDebounced(); + break; + } +} + +function ensureAttachmentsExist() { + if (!Array.isArray(extension_settings.attachments)) { + extension_settings.attachments = []; + } + + if (!Array.isArray(chat_metadata.attachments)) { + chat_metadata.attachments = []; + } + + if (this_chid !== undefined && characters[this_chid]) { + if (!extension_settings.character_attachments) { + extension_settings.character_attachments = {}; + } + + if (!Array.isArray(extension_settings.character_attachments[characters[this_chid].avatar])) { + extension_settings.character_attachments[characters[this_chid].avatar] = []; + } + } +} + +/** + * Gets all currently available attachments. + * @returns {FileAttachment[]} List of attachments + */ +export function getDataBankAttachments() { + ensureAttachmentsExist(); + const globalAttachments = extension_settings.attachments ?? []; + const chatAttachments = chat_metadata.attachments ?? []; + const characterAttachments = extension_settings.character_attachments?.[characters[this_chid]?.avatar] ?? []; + + return [...globalAttachments, ...chatAttachments, ...characterAttachments]; +} + +/** + * Gets all attachments for a specific source. + * @param {string} source Attachment source + * @returns {FileAttachment[]} List of attachments + */ +export function getDataBankAttachmentsForSource(source) { + ensureAttachmentsExist(); + + switch (source) { + case ATTACHMENT_SOURCE.GLOBAL: + return extension_settings.attachments ?? []; + case ATTACHMENT_SOURCE.CHAT: + return chat_metadata.attachments ?? []; + case ATTACHMENT_SOURCE.CHARACTER: + return extension_settings.character_attachments?.[characters[this_chid]?.avatar] ?? []; + } +} + +/** + * Registers a file converter function. + * @param {string} mimeType MIME type + * @param {ConverterFunction} converter Function to convert file + * @returns {void} + */ +export function registerFileConverter(mimeType, converter) { + if (typeof mimeType !== 'string' || typeof converter !== 'function') { + console.error('Invalid converter registration'); + return; + } + + if (Object.keys(converters).includes(mimeType)) { + console.error('Converter already registered'); + return; + } + + converters[mimeType] = converter; } jQuery(function () { @@ -507,6 +1089,11 @@ jQuery(function () { $('#file_form_input').trigger('click'); }); + // Do not change. #manageAttachments is added by extension. + $(document).on('click', '#manageAttachments', function () { + openAttachmentManager(); + }); + $(document).on('click', '.mes_embed', function () { const messageBlock = $(this).closest('.mes'); const messageId = Number(messageBlock.attr('mesid')); @@ -598,6 +1185,9 @@ jQuery(function () { reloadCurrentChat(); }); + $(document).on('click', '.mes_img_enlarge', enlargeMessageImage); + $(document).on('click', '.mes_img_delete', deleteMessageImage); + $('#file_form_input').on('change', onFileAttach); $('#file_form').on('reset', function () { $('#file_form').addClass('displayNone'); diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 26e9e58dd..6f309df69 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -145,6 +145,8 @@ const extension_settings = { variables: { global: {}, }, + attachments: [], + character_attachments: {}, }; let modules = []; diff --git a/public/scripts/extensions/attachments/buttons.html b/public/scripts/extensions/attachments/buttons.html new file mode 100644 index 000000000..0e9adde85 --- /dev/null +++ b/public/scripts/extensions/attachments/buttons.html @@ -0,0 +1,9 @@ +
+
+ Attach a File +
+ +
+
+ Open Data Bank +
diff --git a/public/scripts/extensions/attachments/fandom-scrape.html b/public/scripts/extensions/attachments/fandom-scrape.html new file mode 100644 index 000000000..681af5e85 --- /dev/null +++ b/public/scripts/extensions/attachments/fandom-scrape.html @@ -0,0 +1,51 @@ +
+
+ + + Examples: + https://harrypotter.fandom.com/ + or + harrypotter + + +
+
+ + + Example: + /(Azkaban|Weasley)/gi + + +
+
+ + + +
+
diff --git a/public/scripts/extensions/attachments/index.js b/public/scripts/extensions/attachments/index.js new file mode 100644 index 000000000..a7f58dbc7 --- /dev/null +++ b/public/scripts/extensions/attachments/index.js @@ -0,0 +1,6 @@ +import { renderExtensionTemplateAsync } from '../../extensions.js'; + +jQuery(async () => { + const buttons = await renderExtensionTemplateAsync('attachments', 'buttons', {}); + $('#extensionsMenu').prepend(buttons); +}); diff --git a/public/scripts/extensions/attachments/manager.html b/public/scripts/extensions/attachments/manager.html new file mode 100644 index 000000000..ecfbe2fbb --- /dev/null +++ b/public/scripts/extensions/attachments/manager.html @@ -0,0 +1,118 @@ +
+

+ + Data Bank + +

+
+ These files will be available for extensions that support attachments (e.g. Vector Storage). +
+
+ Supported file types: Plain Text, PDF, Markdown, HTML, EPUB. +
+
+ + + +
+
+

+ + Global Attachments + + +

+ + These files are available for all characters in all chats. + +
+
+
+
+

+ + Character Attachments + + +

+
+ + + + These files are available the current character in all chats they are in. + + + + Saved locally. Not exported. + + + +
+
+
+
+
+

+ + Chat Attachments + + +

+
+ + + These files are available to all characters in the current chat. + +
+
+
+ +
+
+
+
+ + +
+
+
+
+
+ +
+
+ + +
+
+ +
+
diff --git a/public/scripts/extensions/attachments/manifest.json b/public/scripts/extensions/attachments/manifest.json new file mode 100644 index 000000000..2037168c2 --- /dev/null +++ b/public/scripts/extensions/attachments/manifest.json @@ -0,0 +1,11 @@ +{ + "display_name": "Chat Attachments", + "loading_order": 3, + "requires": [], + "optional": [], + "js": "index.js", + "css": "style.css", + "author": "Cohee1207", + "version": "1.0.0", + "homePage": "https://github.com/SillyTavern/SillyTavern" +} diff --git a/public/scripts/extensions/attachments/notepad.html b/public/scripts/extensions/attachments/notepad.html new file mode 100644 index 000000000..899d4dfbb --- /dev/null +++ b/public/scripts/extensions/attachments/notepad.html @@ -0,0 +1,10 @@ +
+ + + + File Content + + +
diff --git a/public/scripts/extensions/attachments/style.css b/public/scripts/extensions/attachments/style.css new file mode 100644 index 000000000..ed13e8bd5 --- /dev/null +++ b/public/scripts/extensions/attachments/style.css @@ -0,0 +1,29 @@ +.attachmentsList:empty { + width: 100%; + height: 100%; +} + +.attachmentsList:empty::before { + display: flex; + align-items: center; + justify-content: center; + content: "No data"; + font-weight: bolder; + width: 100%; + height: 100%; + opacity: 0.8; + min-height: 3rem; +} + +.attachmentListItem { + padding: 10px; +} + +.attachmentListItemSize { + min-width: 4em; + text-align: right; +} + +.attachmentListItemCreated { + text-align: right; +} diff --git a/public/scripts/extensions/attachments/web-scrape.html b/public/scripts/extensions/attachments/web-scrape.html new file mode 100644 index 000000000..5a6129c52 --- /dev/null +++ b/public/scripts/extensions/attachments/web-scrape.html @@ -0,0 +1,3 @@ +
+ Enter web URLs to scrape (one per line): +
diff --git a/public/scripts/extensions/attachments/youtube-scrape.html b/public/scripts/extensions/attachments/youtube-scrape.html new file mode 100644 index 000000000..298b08159 --- /dev/null +++ b/public/scripts/extensions/attachments/youtube-scrape.html @@ -0,0 +1,20 @@ +
+ + Enter a video URL or ID to download its transcript. + +
+ Examples: +
+
    +
  • https://www.youtube.com/watch?v=jV1vkHv4zq8
  • +
  • https://youtu.be/nlLhw1mtCFA
  • +
  • TDpxx5UqrVU
  • +
+ + + +
diff --git a/public/scripts/extensions/caption/index.js b/public/scripts/extensions/caption/index.js index 5f49d0a31..572d02217 100644 --- a/public/scripts/extensions/caption/index.js +++ b/public/scripts/extensions/caption/index.js @@ -310,14 +310,8 @@ jQuery(function () {
Generate Caption
`); - const attachFileButton = $(` -
-
- Attach a File -
`); $('#extensionsMenu').prepend(sendButton); - $('#extensionsMenu').prepend(attachFileButton); $(sendButton).on('click', () => { const hasCaptionModule = (modules.includes('caption') && extension_settings.caption.source === 'extras') || diff --git a/public/scripts/extensions/expressions/index.js b/public/scripts/extensions/expressions/index.js index 9c763e550..8ff0ac935 100644 --- a/public/scripts/extensions/expressions/index.js +++ b/public/scripts/extensions/expressions/index.js @@ -507,6 +507,10 @@ async function loadTalkingHead() { }, body: JSON.stringify(emotionsSettings), }); + + if (!apiResult.ok) { + throw new Error(apiResult.statusText); + } } catch (error) { // it's ok if not supported @@ -539,6 +543,10 @@ async function loadTalkingHead() { }, body: JSON.stringify(animatorSettings), }); + + if (!apiResult.ok) { + throw new Error(apiResult.statusText); + } } catch (error) { // it's ok if not supported diff --git a/public/scripts/extensions/memory/index.js b/public/scripts/extensions/memory/index.js index 323f57e80..cb6bf95d5 100644 --- a/public/scripts/extensions/memory/index.js +++ b/public/scripts/extensions/memory/index.js @@ -1,4 +1,4 @@ -import { getStringHash, debounce, waitUntilCondition, extractAllWords, delay } from '../../utils.js'; +import { getStringHash, debounce, waitUntilCondition, extractAllWords } from '../../utils.js'; import { getContext, getApiUrl, extension_settings, doExtrasFetch, modules, renderExtensionTemplateAsync } from '../../extensions.js'; import { activateSendButtons, diff --git a/public/scripts/extensions/shared.js b/public/scripts/extensions/shared.js index eb41e850c..0fa2137db 100644 --- a/public/scripts/extensions/shared.js +++ b/public/scripts/extensions/shared.js @@ -23,7 +23,6 @@ export async function getMultimodalCaption(base64Img, prompt) { // OpenRouter has a payload limit of ~2MB. Google is 4MB, but we love democracy. // Ooba requires all images to be JPEGs. Koboldcpp just asked nicely. const isGoogle = extension_settings.caption.multimodal_api === 'google'; - const isClaude = extension_settings.caption.multimodal_api === 'anthropic'; const isOllama = extension_settings.caption.multimodal_api === 'ollama'; const isLlamaCpp = extension_settings.caption.multimodal_api === 'llamacpp'; const isCustom = extension_settings.caption.multimodal_api === 'custom'; diff --git a/public/scripts/extensions/tts/alltalk.js b/public/scripts/extensions/tts/alltalk.js index eb04e500d..716986033 100644 --- a/public/scripts/extensions/tts/alltalk.js +++ b/public/scripts/extensions/tts/alltalk.js @@ -433,8 +433,8 @@ class AllTalkTtsProvider { updateLanguageDropdown() { const languageSelect = document.getElementById('language_options'); if (languageSelect) { - // Ensure default language is set - this.settings.language = this.settings.language; + // Ensure default language is set (??? whatever that means) + // this.settings.language = this.settings.language; languageSelect.innerHTML = ''; for (let language in this.languageLabels) { diff --git a/public/scripts/extensions/vectors/index.js b/public/scripts/extensions/vectors/index.js index 8d3113e6f..6ff5c6af5 100644 --- a/public/scripts/extensions/vectors/index.js +++ b/public/scripts/extensions/vectors/index.js @@ -2,6 +2,7 @@ import { eventSource, event_types, extension_prompt_types, + extension_prompt_roles, getCurrentChatId, getRequestHeaders, is_send_press, @@ -20,11 +21,13 @@ import { } from '../../extensions.js'; import { collapseNewlines } from '../../power-user.js'; import { SECRET_KEYS, secret_state, writeSecret } from '../../secrets.js'; +import { getDataBankAttachments, getFileAttachment } from '../../chats.js'; import { debounce, getStringHash as calculateHash, waitUntilCondition, onlyUnique, splitRecursive } from '../../utils.js'; const MODULE_NAME = 'vectors'; export const EXTENSION_PROMPT_TAG = '3_vectors'; +export const EXTENSION_PROMPT_TAG_DB = '4_vectors_data_bank'; const settings = { // For both @@ -32,6 +35,7 @@ const settings = { include_wi: false, togetherai_model: 'togethercomputer/m2-bert-80M-32k-retrieval', openai_model: 'text-embedding-ada-002', + cohere_model: 'embed-english-v3.0', summarize: false, summarize_sent: false, summary_source: 'main', @@ -39,7 +43,7 @@ const settings = { // For chats enabled_chats: false, - template: 'Past events: {{text}}', + template: 'Past events:\n{{text}}', depth: 2, position: extension_prompt_types.IN_PROMPT, protect: 5, @@ -49,13 +53,32 @@ const settings = { // For files enabled_files: false, + translate_files: false, size_threshold: 10, chunk_size: 5000, chunk_count: 2, + + // For Data Bank + size_threshold_db: 5, + chunk_size_db: 2500, + chunk_count_db: 5, + file_template_db: 'Related information:\n{{text}}', + file_position_db: extension_prompt_types.IN_PROMPT, + file_depth_db: 4, + file_depth_role_db: extension_prompt_roles.SYSTEM, }; const moduleWorker = new ModuleWorkerWrapper(synchronizeChat); +/** + * Gets the Collection ID for a file embedded in the chat. + * @param {string} fileUrl URL of the file + * @returns {string} Collection ID + */ +function getFileCollectionId(fileUrl) { + return `file_${getStringHash(fileUrl)}`; +} + async function onVectorizeAllClick() { try { if (!settings.enabled_chats) { @@ -292,6 +315,34 @@ async function processFiles(chat) { return; } + const dataBank = getDataBankAttachments(); + const dataBankCollectionIds = []; + + for (const file of dataBank) { + const collectionId = getFileCollectionId(file.url); + const hashesInCollection = await getSavedHashes(collectionId); + dataBankCollectionIds.push(collectionId); + + // File is already in the collection + if (hashesInCollection.length) { + continue; + } + + // Download and process the file + file.text = await getFileAttachment(file.url); + console.log(`Vectors: Retrieved file ${file.name} from Data Bank`); + // Convert kilobytes to string length + const thresholdLength = settings.size_threshold_db * 1024; + // Use chunk size from settings if file is larger than threshold + const chunkSize = file.size > thresholdLength ? settings.chunk_size_db : -1; + await vectorizeFile(file.text, file.name, collectionId, chunkSize); + } + + if (dataBankCollectionIds.length) { + const queryText = await getQueryText(chat); + await injectDataBankChunks(queryText, dataBankCollectionIds); + } + for (const message of chat) { // Message has no file if (!message?.extra?.file) { @@ -300,8 +351,7 @@ async function processFiles(chat) { // Trim file inserted by the script const fileText = String(message.mes) - .substring(0, message.extra.fileLength).trim() - .replace(/^```/, '').replace(/```$/, '').trim(); + .substring(0, message.extra.fileLength).trim(); // Convert kilobytes to string length const thresholdLength = settings.size_threshold * 1024; @@ -314,25 +364,55 @@ async function processFiles(chat) { message.mes = message.mes.substring(message.extra.fileLength); const fileName = message.extra.file.name; - const collectionId = `file_${getStringHash(fileName)}`; + const fileUrl = message.extra.file.url; + const collectionId = getFileCollectionId(fileUrl); const hashesInCollection = await getSavedHashes(collectionId); // File is already in the collection if (!hashesInCollection.length) { - await vectorizeFile(fileText, fileName, collectionId); + await vectorizeFile(fileText, fileName, collectionId, settings.chunk_size); } const queryText = await getQueryText(chat); const fileChunks = await retrieveFileChunks(queryText, collectionId); - // Wrap it back in a code block - message.mes = `\`\`\`\n${fileChunks}\n\`\`\`\n\n${message.mes}`; + message.mes = `${fileChunks}\n\n${message.mes}`; } } catch (error) { console.error('Vectors: Failed to retrieve files', error); } } +/** + * Inserts file chunks from the Data Bank into the prompt. + * @param {string} queryText Text to query + * @param {string[]} collectionIds File collection IDs + * @returns {Promise} + */ +async function injectDataBankChunks(queryText, collectionIds) { + try { + const queryResults = await queryMultipleCollections(collectionIds, queryText, settings.chunk_count_db); + console.debug(`Vectors: Retrieved ${collectionIds.length} Data Bank collections`, queryResults); + let textResult = ''; + + for (const collectionId in queryResults) { + console.debug(`Vectors: Processing Data Bank collection ${collectionId}`, queryResults[collectionId]); + const metadata = queryResults[collectionId].metadata?.filter(x => x.text)?.sort((a, b) => a.index - b.index)?.map(x => x.text)?.filter(onlyUnique) || []; + textResult += metadata.join('\n') + '\n\n'; + } + + if (!textResult) { + console.debug('Vectors: No Data Bank chunks found'); + return; + } + + const insertedText = substituteParams(settings.file_template_db.replace(/{{text}}/i, textResult)); + setExtensionPrompt(EXTENSION_PROMPT_TAG_DB, insertedText, settings.file_position_db, settings.file_depth_db, settings.include_wi, settings.file_depth_role_db); + } catch (error) { + console.error('Vectors: Failed to insert Data Bank chunks', error); + } +} + /** * Retrieves file chunks from the vector index and inserts them into the chat. * @param {string} queryText Text to query @@ -354,16 +434,24 @@ async function retrieveFileChunks(queryText, collectionId) { * @param {string} fileText File text * @param {string} fileName File name * @param {string} collectionId File collection ID + * @param {number} chunkSize Chunk size */ -async function vectorizeFile(fileText, fileName, collectionId) { +async function vectorizeFile(fileText, fileName, collectionId, chunkSize) { try { - toastr.info('Vectorization may take some time, please wait...', `Ingesting file ${fileName}`); - const chunks = splitRecursive(fileText, settings.chunk_size); + if (settings.translate_files && typeof window['translate'] === 'function') { + console.log(`Vectors: Translating file ${fileName} to English...`); + const translatedText = await window['translate'](fileText, 'en'); + fileText = translatedText; + } + + const toast = toastr.info('Vectorization may take some time, please wait...', `Ingesting file ${fileName}`); + const chunks = splitRecursive(fileText, chunkSize); console.debug(`Vectors: Split file ${fileName} into ${chunks.length} chunks`, chunks); const items = chunks.map((chunk, index) => ({ hash: getStringHash(chunk), text: chunk, index: index })); await insertVectorItems(collectionId, items); + toastr.clear(toast); console.log(`Vectors: Inserted ${chunks.length} vector items for file ${fileName} into ${collectionId}`); } catch (error) { console.error('Vectors: Failed to vectorize file', error); @@ -377,7 +465,8 @@ async function vectorizeFile(fileText, fileName, collectionId) { async function rearrangeChat(chat) { try { // Clear the extension prompt - setExtensionPrompt(EXTENSION_PROMPT_TAG, '', extension_prompt_types.IN_PROMPT, 0, settings.include_wi); + setExtensionPrompt(EXTENSION_PROMPT_TAG, '', settings.position, settings.depth, settings.include_wi); + setExtensionPrompt(EXTENSION_PROMPT_TAG_DB, '', settings.file_position_db, settings.file_depth_db, settings.include_wi, settings.file_depth_role_db); if (settings.enabled_files) { await processFiles(chat); @@ -526,6 +615,9 @@ function getVectorHeaders() { case 'openai': addOpenAiHeaders(headers); break; + case 'cohere': + addCohereHeaders(headers); + break; default: break; } @@ -564,6 +656,16 @@ function addOpenAiHeaders(headers) { }); } +/** + * Add headers for the Cohere API source. + * @param {object} headers Header object + */ +function addCohereHeaders(headers) { + Object.assign(headers, { + 'X-Cohere-Model': extension_settings.vectors.cohere_model, + }); +} + /** * Inserts vector items into a collection * @param {string} collectionId - The collection to insert into @@ -575,7 +677,8 @@ async function insertVectorItems(collectionId, items) { settings.source === 'palm' && !secret_state[SECRET_KEYS.MAKERSUITE] || settings.source === 'mistral' && !secret_state[SECRET_KEYS.MISTRALAI] || settings.source === 'togetherai' && !secret_state[SECRET_KEYS.TOGETHERAI] || - settings.source === 'nomicai' && !secret_state[SECRET_KEYS.NOMICAI]) { + settings.source === 'nomicai' && !secret_state[SECRET_KEYS.NOMICAI] || + settings.source === 'cohere' && !secret_state[SECRET_KEYS.COHERE]) { throw new Error('Vectors: API key missing', { cause: 'api_key_missing' }); } @@ -649,6 +752,65 @@ async function queryCollection(collectionId, searchText, topK) { return await response.json(); } +/** + * Queries multiple collections for a given text. + * @param {string[]} collectionIds - Collection IDs to query + * @param {string} searchText - Text to query + * @param {number} topK - Number of results to return + * @returns {Promise>} - Results mapped to collection IDs + */ +async function queryMultipleCollections(collectionIds, searchText, topK) { + const headers = getVectorHeaders(); + + const response = await fetch('/api/vector/query-multi', { + method: 'POST', + headers: headers, + body: JSON.stringify({ + collectionIds: collectionIds, + searchText: searchText, + topK: topK, + source: settings.source, + }), + }); + + if (!response.ok) { + throw new Error('Failed to query multiple collections'); + } + + return await response.json(); +} + +/** + * Purges the vector index for a file. + * @param {string} fileUrl File URL to purge + */ +async function purgeFileVectorIndex(fileUrl) { + try { + if (!settings.enabled_files) { + return; + } + + console.log(`Vectors: Purging file vector index for ${fileUrl}`); + const collectionId = getFileCollectionId(fileUrl); + + const response = await fetch('/api/vector/purge', { + method: 'POST', + headers: getRequestHeaders(), + body: JSON.stringify({ + collectionId: collectionId, + }), + }); + + if (!response.ok) { + throw new Error(`Could not delete vector index for collection ${collectionId}`); + } + + console.log(`Vectors: Purged vector index for collection ${collectionId}`); + } catch (error) { + console.error('Vectors: Failed to purge file', error); + } +} + /** * Purges the vector index for a collection. * @param {string} collectionId Collection ID to purge @@ -685,6 +847,7 @@ function toggleSettings() { $('#vectors_chats_settings').toggle(!!settings.enabled_chats); $('#together_vectorsModel').toggle(settings.source === 'togetherai'); $('#openai_vectorsModel').toggle(settings.source === 'openai'); + $('#cohere_vectorsModel').toggle(settings.source === 'cohere'); $('#nomicai_apiKey').toggle(settings.source === 'nomicai'); } @@ -728,6 +891,49 @@ async function onViewStatsClick() { } +async function onVectorizeAllFilesClick() { + try { + const dataBank = getDataBankAttachments(); + const chatAttachments = getContext().chat.filter(x => x.extra?.file).map(x => x.extra.file); + const allFiles = [...dataBank, ...chatAttachments]; + + for (const file of allFiles) { + const text = await getFileAttachment(file.url); + const collectionId = getFileCollectionId(file.url); + const hashes = await getSavedHashes(collectionId); + + if (hashes.length) { + console.log(`Vectors: File ${file.name} is already vectorized`); + continue; + } + + await vectorizeFile(text, file.name, collectionId, settings.chunk_size); + } + + toastr.success('All files vectorized', 'Vectorization successful'); + } catch (error) { + console.error('Vectors: Failed to vectorize all files', error); + toastr.error('Failed to vectorize all files', 'Vectorization failed'); + } +} + +async function onPurgeFilesClick() { + try { + const dataBank = getDataBankAttachments(); + const chatAttachments = getContext().chat.filter(x => x.extra?.file).map(x => x.extra.file); + const allFiles = [...dataBank, ...chatAttachments]; + + for (const file of allFiles) { + await purgeFileVectorIndex(file.url); + } + + toastr.success('All files purged', 'Purge successful'); + } catch (error) { + console.error('Vectors: Failed to purge all files', error); + toastr.error('Failed to purge all files', 'Purge failed'); + } +} + jQuery(async () => { if (!extension_settings.vectors) { extension_settings.vectors = settings; @@ -782,6 +988,12 @@ jQuery(async () => { Object.assign(extension_settings.vectors, settings); saveSettingsDebounced(); }); + $('#vectors_cohere_model').val(settings.cohere_model).on('change', () => { + $('#vectors_modelWarning').show(); + settings.cohere_model = String($('#vectors_cohere_model').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); $('#vectors_template').val(settings.template).on('input', () => { settings.template = String($('#vectors_template').val()); Object.assign(extension_settings.vectors, settings); @@ -816,6 +1028,8 @@ jQuery(async () => { $('#vectors_vectorize_all').on('click', onVectorizeAllClick); $('#vectors_purge').on('click', onPurgeClick); $('#vectors_view_stats').on('click', onViewStatsClick); + $('#vectors_files_vectorize_all').on('click', onVectorizeAllFilesClick); + $('#vectors_files_purge').on('click', onPurgeFilesClick); $('#vectors_size_threshold').val(settings.size_threshold).on('input', () => { settings.size_threshold = Number($('#vectors_size_threshold').val()); @@ -871,6 +1085,55 @@ jQuery(async () => { saveSettingsDebounced(); }); + $('#vectors_size_threshold_db').val(settings.size_threshold_db).on('input', () => { + settings.size_threshold_db = Number($('#vectors_size_threshold_db').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + + $('#vectors_chunk_size_db').val(settings.chunk_size_db).on('input', () => { + settings.chunk_size_db = Number($('#vectors_chunk_size_db').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + + $('#vectors_chunk_count_db').val(settings.chunk_count_db).on('input', () => { + settings.chunk_count_db = Number($('#vectors_chunk_count_db').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + + $('#vectors_file_template_db').val(settings.file_template_db).on('input', () => { + settings.file_template_db = String($('#vectors_file_template_db').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + + $(`input[name="vectors_file_position_db"][value="${settings.file_position_db}"]`).prop('checked', true); + $('input[name="vectors_file_position_db"]').on('change', () => { + settings.file_position_db = Number($('input[name="vectors_file_position_db"]:checked').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + + $('#vectors_file_depth_db').val(settings.file_depth_db).on('input', () => { + settings.file_depth_db = Number($('#vectors_file_depth_db').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + + $('#vectors_file_depth_role_db').val(settings.file_depth_role_db).on('input', () => { + settings.file_depth_role_db = Number($('#vectors_file_depth_role_db').val()); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + + $('#vectors_translate_files').prop('checked', settings.translate_files).on('input', () => { + settings.translate_files = !!$('#vectors_translate_files').prop('checked'); + Object.assign(extension_settings.vectors, settings); + saveSettingsDebounced(); + }); + const validSecret = !!secret_state[SECRET_KEYS.NOMICAI]; const placeholder = validSecret ? '✔️ Key saved' : '❌ Missing key'; $('#api_key_nomicai').attr('placeholder', placeholder); @@ -883,4 +1146,5 @@ jQuery(async () => { eventSource.on(event_types.MESSAGE_SWIPED, onChatEvent); eventSource.on(event_types.CHAT_DELETED, purgeVectorIndex); eventSource.on(event_types.GROUP_CHAT_DELETED, purgeVectorIndex); + eventSource.on(event_types.FILE_ATTACHMENT_DELETED, purgeFileVectorIndex); }); diff --git a/public/scripts/extensions/vectors/settings.html b/public/scripts/extensions/vectors/settings.html index 5244558eb..02499d120 100644 --- a/public/scripts/extensions/vectors/settings.html +++ b/public/scripts/extensions/vectors/settings.html @@ -10,13 +10,14 @@ Vectorization Source
@@ -29,6 +30,20 @@
+
+ + +
-
+
+ +
+ Message attachments +
+
+ Data Bank files +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + + +
+ + + + +
+
+
+ + +

@@ -129,9 +214,9 @@
- +